A Flutter mobile app built for a coding test that displays countries with Clean Architecture, BLoC pattern, and offline support.
✅ Complete: 77.5% test coverage, all coding test requirements met.
- 🌐 Countries List: Browse countries with flags, names, and capitals
- 📱 Country Details: View population, area, languages, and coat of arms
- 🔄 Pull-to-Refresh: Refresh data with pull gesture
- 📶 Offline Support: Cached data when offline
- 🎨 Modern UI: Material 3 design with hero animations
Clean Architecture with clear separation:
UI Layer → BLoC → Use Cases → Repository → Data Sources
# Clone and install
git clone <repository-url>
cd countries_explorer
flutter pub get
# Run the app
flutter run # Android
flutter run -d ios # iOS (macOS only)29 focused tests with 77.5% coverage on domain/data layers:
# Run tests
flutter test
# Run with coverage
flutter test --coverage
genhtml coverage/lcov.info -o coverage/html
open coverage/html/index.htmlTest Statistics:
- 7 test files, 673 lines, 29 tests
- Domain Layer: 100% coverage
- Data Layer: 77.5% coverage
- Overall: 77.5% coverage (exceeds >70% target)
REST Countries API integration:
- Base URL:
https://restcountries.com/v3.1/ - Caching: SharedPreferences for offline support
- Strategy: Remote-first with local fallback
- Flutter: ^3.9.2
- State Management: BLoC (flutter_bloc)
- Dependency Injection: get_it
- Functional Programming: dartz (Either type)
- HTTP Client: http
- Local Storage: shared_preferences
- Testing: flutter_test + mocktail + bloc_test
- Status: Fully functional
- Features: All features working including network, caching, and UI
- Permissions: INTERNET permission configured
- Network: HTTPS API calls with proper security
- Web/Desktop: Removed (mobile-focused app)
flutter_bloc: State managementdartz: Functional programming utilitieshttp: HTTP client for API callsshared_preferences: Local data storageget_it: Dependency injectionequatable: Value equality for objects
flutter_test: Testing frameworkmocktail: Mocking utilitiesbloc_test: BLoC testing utilities
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- REST Countries API for providing free country data
- Flutter team for the amazing framework
- Clean Architecture principles by Uncle Bob
- BLoC pattern by Felix Angelov
Built with ❤️ using Flutter for Android & iOS