advanced-games-library
Version:
Advanced Gaming Library for React Native - Four Complete Games with iOS Compatibility Fixes
253 lines (214 loc) • 8.29 kB
text/typescript
import { GameManager } from '../services/GameManager';
import { PlayerService } from '../services/PlayerService';
import { StorageService } from '../services/StorageService';
import { AnalyticsService } from '../services/AnalyticsService';
import { CustomizationService } from '../services/CustomizationService';
import {
LibraryConfig,
PlayerData,
GameDifficulty,
GameLibraryError,
GameErrorCode
} from '../core/types';
import { DEFAULT_CONFIG } from '../core/config';
// Mock the services
jest.mock('../services/PlayerService');
jest.mock('../services/StorageService');
jest.mock('../services/AnalyticsService');
jest.mock('../services/CustomizationService');
describe('GameManager', () => {
let gameManager: GameManager;
let mockPlayerService: jest.Mocked<PlayerService>;
let mockStorageService: jest.Mocked<StorageService>;
let mockAnalyticsService: jest.Mocked<AnalyticsService>;
let mockCustomizationService: jest.Mocked<CustomizationService>;
beforeEach(() => {
// Reset singleton
(GameManager as any).instance = undefined;
gameManager = GameManager.getInstance();
// Setup mocks
mockStorageService = new StorageService() as jest.Mocked<StorageService>;
mockPlayerService = new PlayerService(mockStorageService) as jest.Mocked<PlayerService>;
mockAnalyticsService = new AnalyticsService(true) as jest.Mocked<AnalyticsService>;
mockCustomizationService = new CustomizationService() as jest.Mocked<CustomizationService>;
// Mock implementations
mockStorageService.initialize.mockResolvedValue();
mockPlayerService.initialize.mockResolvedValue();
mockAnalyticsService.initialize.mockResolvedValue();
mockCustomizationService.initialize.mockResolvedValue();
mockCustomizationService.getCurrentTheme.mockReturnValue(DEFAULT_CONFIG.defaultTheme);
});
afterEach(() => {
jest.clearAllMocks();
});
describe('Singleton Pattern', () => {
it('should return the same instance', () => {
const instance1 = GameManager.getInstance();
const instance2 = GameManager.getInstance();
expect(instance1).toBe(instance2);
});
});
describe('Initialization', () => {
it('should initialize successfully with valid config', async () => {
const config: LibraryConfig = {
enableAnalytics: true,
enableStorage: true,
defaultTheme: DEFAULT_CONFIG.defaultTheme
};
await expect(gameManager.initialize(config)).resolves.not.toThrow();
});
it('should throw error if already initialized', async () => {
const config: LibraryConfig = {
enableAnalytics: true,
enableStorage: true,
defaultTheme: DEFAULT_CONFIG.defaultTheme
};
await gameManager.initialize(config);
await expect(gameManager.initialize(config)).rejects.toThrow(GameLibraryError);
await expect(gameManager.initialize(config)).rejects.toThrow('already initialized');
});
it('should handle initialization failure gracefully', async () => {
mockStorageService.initialize.mockRejectedValue(new Error('Storage failed'));
const config: LibraryConfig = {
enableAnalytics: true,
enableStorage: true,
defaultTheme: DEFAULT_CONFIG.defaultTheme
};
await expect(gameManager.initialize(config)).rejects.toThrow(GameLibraryError);
});
});
describe('Player Management', () => {
beforeEach(async () => {
const config: LibraryConfig = {
enableAnalytics: true,
enableStorage: true,
defaultTheme: DEFAULT_CONFIG.defaultTheme
};
await gameManager.initialize(config);
});
it('should set player data successfully', () => {
const playerData: PlayerData = {
playerId: 'test123',
firstName: 'Test',
lastName: 'User',
createdAt: new Date(),
lastActive: new Date(),
totalGamesPlayed: 0,
achievements: []
};
expect(() => gameManager.setPlayer(playerData)).not.toThrow();
expect(mockPlayerService.setPlayerData).toHaveBeenCalledWith(playerData);
});
it('should get player data', () => {
const mockPlayerData: PlayerData = {
playerId: 'test123',
firstName: 'Test',
lastName: 'User',
createdAt: new Date(),
lastActive: new Date(),
totalGamesPlayed: 5,
achievements: []
};
mockPlayerService.getPlayerData.mockReturnValue(mockPlayerData);
const result = gameManager.getPlayer();
expect(result).toEqual(mockPlayerData);
expect(mockPlayerService.getPlayerData).toHaveBeenCalled();
});
it('should throw error when setting player without initialization', () => {
const uninitializedManager = new (GameManager as any)();
const playerData: PlayerData = {
playerId: 'test123',
firstName: 'Test',
lastName: 'User',
createdAt: new Date(),
lastActive: new Date(),
totalGamesPlayed: 0,
achievements: []
};
expect(() => uninitializedManager.setPlayer(playerData)).toThrow(GameLibraryError);
});
});
describe('Game Management', () => {
beforeEach(async () => {
const config: LibraryConfig = {
enableAnalytics: true,
enableStorage: true,
defaultTheme: DEFAULT_CONFIG.defaultTheme
};
await gameManager.initialize(config);
});
it('should return empty array for available games initially', () => {
const games = gameManager.getAvailableGames();
expect(Array.isArray(games)).toBe(true);
expect(games).toHaveLength(0);
});
it('should throw error when launching non-existent game', async () => {
await expect(gameManager.launchGame('non-existent-game')).rejects.toThrow(GameLibraryError);
await expect(gameManager.launchGame('non-existent-game')).rejects.toThrow('not found');
});
});
describe('Event Handling', () => {
beforeEach(async () => {
const config: LibraryConfig = {
enableAnalytics: true,
enableStorage: true,
defaultTheme: DEFAULT_CONFIG.defaultTheme
};
await gameManager.initialize(config);
});
it('should register game complete callback', () => {
const callback = jest.fn();
expect(() => gameManager.onGameComplete(callback)).not.toThrow();
});
it('should register game start callback', () => {
const callback = jest.fn();
expect(() => gameManager.onGameStart(callback)).not.toThrow();
});
it('should register score update callback', () => {
const callback = jest.fn();
expect(() => gameManager.onScoreUpdate(callback)).not.toThrow();
});
});
describe('Cleanup', () => {
it('should cleanup without errors', () => {
expect(() => gameManager.destroy()).not.toThrow();
});
it('should clear all data on destroy', () => {
gameManager.destroy();
// The manager should be reset to uninitialized state
const playerData: PlayerData = {
playerId: 'test123',
firstName: 'Test',
lastName: 'User',
createdAt: new Date(),
lastActive: new Date(),
totalGamesPlayed: 0,
achievements: []
};
expect(() => gameManager.setPlayer(playerData)).toThrow(GameLibraryError);
});
});
describe('Error Handling', () => {
it('should handle invalid game configuration', async () => {
const config: LibraryConfig = {
enableAnalytics: true,
enableStorage: true,
defaultTheme: DEFAULT_CONFIG.defaultTheme
};
await gameManager.initialize(config);
// This should work once we have a real game registered
await expect(gameManager.launchGame('invalid-game')).rejects.toThrow(GameLibraryError);
});
it('should handle storage errors gracefully', async () => {
mockStorageService.getGameResults.mockRejectedValue(new Error('Storage error'));
const config: LibraryConfig = {
enableAnalytics: true,
enableStorage: true,
defaultTheme: DEFAULT_CONFIG.defaultTheme
};
await gameManager.initialize(config);
const history = await gameManager.getGameHistory();
expect(history).toEqual([]);
});
});
});