feat: add vehicle customization, Arabic search normalization, and smooth movement interpolation

This commit is contained in:
Hamza-Ayed
2026-09-19 12:34:25 +03:00
parent 43ad2e0ad4
commit 55830beee8
16 changed files with 2295 additions and 393 deletions
@@ -0,0 +1,88 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:siro_maps/core/services/vehicle_icon_generator.dart';
import 'package:siro_maps/core/utils/arabic_search_normalizer.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
group('ArabicSearchNormalizer Tests', () {
test('Normalizes diacritics and tashkeel', () {
const input = 'مَدِينَةُ عَمَّانَ';
expect(ArabicSearchNormalizer.normalize(input), equals('مدينه عمان'));
});
test('Normalizes various forms of Alef', () {
expect(ArabicSearchNormalizer.normalize('أحمد'), equals('احمد'));
expect(ArabicSearchNormalizer.normalize('إبراهيم'), equals('ابراهيم'));
expect(ArabicSearchNormalizer.normalize('آلاء'), equals('الاء'));
expect(ArabicSearchNormalizer.normalize('ٱستقبال'), equals('استقبال'));
});
test('Normalizes Teh Marbuta and Alef Maqsura', () {
expect(ArabicSearchNormalizer.normalize('مستشفى'), equals('مستشفي'));
expect(ArabicSearchNormalizer.normalize('جامعة'), equals('جامعه'));
expect(ArabicSearchNormalizer.normalize('صيدلية النهدي'), equals('صيدليه النهدي'));
});
test('Matches normalized queries flexibly', () {
expect(
ArabicSearchNormalizer.matches('صيدلية النهدي الكبرى', 'نهدي'),
isTrue,
);
expect(
ArabicSearchNormalizer.matches('مستشفى الجامعة الأردنية', 'جامعة'),
isTrue,
);
expect(
ArabicSearchNormalizer.matches('مستشفى الجامعة الأردنية', 'جامعه'),
isTrue,
);
expect(
ArabicSearchNormalizer.matches('مطعم القدس', 'القدس'),
isTrue,
);
});
});
group('VehicleIconGenerator Tests', () {
test('Generates valid PNG bytes for modern sedan', () async {
final bytes = await VehicleIconGenerator.generateVehicleIconBytes(
styleId: 'car',
primaryColor: const Color(0xFF007AFF),
);
expect(bytes, isNotEmpty);
// Valid PNG header starts with 0x89, 'P', 'N', 'G' (0x89, 0x50, 0x4E, 0x47)
expect(bytes[0], equals(0x89));
expect(bytes[1], equals(0x50));
expect(bytes[2], equals(0x4E));
expect(bytes[3], equals(0x47));
});
test('Generates valid PNG bytes for SUV and Arrow styles', () async {
final suvBytes = await VehicleIconGenerator.generateVehicleIconBytes(
styleId: 'suv',
primaryColor: const Color(0xFF00C853),
);
expect(suvBytes, isNotEmpty);
expect(suvBytes[0], equals(0x89));
final arrowBytes = await VehicleIconGenerator.generateVehicleIconBytes(
styleId: 'arrow',
primaryColor: const Color(0xFFFF3B30),
);
expect(arrowBytes, isNotEmpty);
expect(arrowBytes[0], equals(0x89));
});
test('Exposes predefined vehicle styles and colors', () {
expect(VehicleIconGenerator.availableStyles, isNotEmpty);
expect(VehicleIconGenerator.availableStyles.any((s) => s.id == 'car'), isTrue);
expect(VehicleIconGenerator.availableStyles.any((s) => s.id == 'suv'), isTrue);
expect(VehicleIconGenerator.availableStyles.any((s) => s.id == 'arrow'), isTrue);
expect(VehicleIconGenerator.availableColors, isNotEmpty);
expect(VehicleIconGenerator.availableColors.any((c) => c.colorValue == 0xFF007AFF), isTrue);
});
});
}