Skip to content

Commit eb88149

Browse files
committed
pref service, theme and language cubit tests added
1 parent 32e3221 commit eb88149

File tree

11 files changed

+270
-45
lines changed

11 files changed

+270
-45
lines changed

lib/bloc/language/language_cubit.dart

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
import 'package:flutter/material.dart';
22
import 'package:flutter_bloc/flutter_bloc.dart';
33

4-
import '../../services/preferences_service.dart';
4+
import '../../contractors/impl_preferences_service.dart';
55

66
class LanguageCubit extends Cubit<Locale> {
7-
LanguageCubit(Locale initialLocale) : super(initialLocale) {
8-
final locale = PreferencesService.instance.locale;
9-
emit(locale ?? initialLocale);
7+
LanguageCubit(this.preferencesService) : super(Locale('en', 'US')) {
8+
final locale = preferencesService.locale;
9+
emit(locale ?? Locale('en', 'US'));
1010
}
1111

12+
final ImplPreferencesService preferencesService;
13+
1214
void changeLocale(Locale locale) async {
1315
if (state == locale) {
1416
return;
1517
}
1618

17-
await PreferencesService.instance.changeLocale(locale);
19+
await preferencesService.changeLocale(locale);
1820
emit(locale);
1921
}
2022
}

lib/bloc/theme/theme_cubit.dart

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
import 'package:flutter/material.dart';
22
import 'package:flutter_bloc/flutter_bloc.dart';
33

4-
import '../../services/preferences_service.dart';
4+
import '../../contractors/impl_preferences_service.dart';
55

66
class ThemeCubit extends Cubit<ThemeMode> {
7-
ThemeCubit(ThemeMode initialThemeMode) : super(initialThemeMode) {
8-
emit(PreferencesService.instance.themeMode ?? initialThemeMode);
7+
ThemeCubit(this.preferencesService) : super(ThemeMode.system) {
8+
emit(preferencesService.themeMode ?? ThemeMode.system);
99
}
1010

11+
ImplPreferencesService preferencesService;
12+
1113
void changeTheme(ThemeMode themeMode) async {
1214
if (state == themeMode) {
1315
return;
1416
}
1517

16-
await PreferencesService.instance.changeThemeMode(themeMode);
18+
await preferencesService.changeThemeMode(themeMode);
1719
emit(themeMode);
1820
}
1921
}

lib/contractors/.gitkeep

Whitespace-only changes.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import 'package:flutter/material.dart';
2+
3+
abstract class ImplPreferencesService {
4+
Future<void> changeThemeMode(ThemeMode themeMode);
5+
ThemeMode? get themeMode;
6+
Future<void> changeLocale(Locale locale);
7+
Locale? get locale;
8+
}

lib/main.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'bloc/language/language_cubit.dart';
55
import 'bloc/theme/theme_cubit.dart';
66
import 'config/init.dart';
77
import 'presentation/app.dart';
8+
import 'services/preferences_service.dart';
89

910
void main() async {
1011
await init();
@@ -13,10 +14,10 @@ void main() async {
1314
MultiBlocProvider(
1415
providers: [
1516
BlocProvider(
16-
create: (_) => ThemeCubit(ThemeMode.system),
17+
create: (_) => ThemeCubit(PreferencesService.instance),
1718
),
1819
BlocProvider(
19-
create: (_) => LanguageCubit(Locale('en', 'US')),
20+
create: (_) => LanguageCubit(PreferencesService.instance),
2021
),
2122
],
2223
child: App(),

lib/services/preferences_service.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import 'dart:async';
33
import 'package:flutter/material.dart';
44
import 'package:shared_preferences/shared_preferences.dart';
55

6-
class PreferencesService {
6+
import '../contractors/impl_preferences_service.dart';
7+
8+
class PreferencesService implements ImplPreferencesService {
79
PreferencesService._();
810

911
static PreferencesService? _instance;
@@ -26,10 +28,12 @@ class PreferencesService {
2628
final _languageCodeKey = 'languageCode';
2729
final _countryCodeKey = 'countryCode';
2830

31+
@override
2932
Future<void> changeThemeMode(ThemeMode themeMode) async {
3033
_sharedPreferences?.setInt(_themeModeKey, themeMode.index);
3134
}
3235

36+
@override
3337
ThemeMode? get themeMode {
3438
final index = _sharedPreferences?.getInt(_themeModeKey);
3539

@@ -40,11 +44,13 @@ class PreferencesService {
4044
return null;
4145
}
4246

47+
@override
4348
Future<void> changeLocale(Locale locale) async {
4449
_sharedPreferences?.setString(_languageCodeKey, locale.languageCode);
4550
_sharedPreferences?.setString(_countryCodeKey, locale.countryCode ?? '');
4651
}
4752

53+
@override
4854
Locale? get locale {
4955
final languageCode = _sharedPreferences?.getString(_languageCodeKey);
5056
final countryCode = _sharedPreferences?.getString(_countryCodeKey);
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import 'package:architecture_example/bloc/language/language_cubit.dart';
2+
import 'package:bloc_test/bloc_test.dart';
3+
import 'package:flutter/material.dart';
4+
import 'package:flutter_test/flutter_test.dart';
5+
6+
import '../mocks/mock_preferences_service.dart';
7+
8+
void main() {
9+
group(
10+
'LanguageCubit without default [Locale]',
11+
() {
12+
late LanguageCubit languageCubit;
13+
14+
setUp(() async {
15+
languageCubit = LanguageCubit(MockPreferencesService());
16+
});
17+
18+
blocTest<LanguageCubit, Locale>(
19+
'default state is [ThemeMode.system]',
20+
build: () => languageCubit,
21+
expect: () => [],
22+
verify: (_) {
23+
expect(languageCubit.state, Locale('en', 'US'));
24+
},
25+
);
26+
27+
blocTest<LanguageCubit, Locale>(
28+
'changeTheme test',
29+
build: () => languageCubit,
30+
act: (cubit) => cubit.changeLocale(Locale('az', 'AZ')),
31+
expect: () => [Locale('az', 'AZ')],
32+
);
33+
34+
tearDown(() {
35+
languageCubit.close();
36+
});
37+
},
38+
);
39+
40+
group(
41+
'ThemeCubit with default [ThemeMode]',
42+
() {
43+
late LanguageCubit languageCubit;
44+
45+
setUp(() async {
46+
final mockPreferencesService = MockPreferencesService();
47+
mockPreferencesService.changeThemeMode(ThemeMode.light);
48+
languageCubit = LanguageCubit(mockPreferencesService);
49+
});
50+
51+
blocTest<LanguageCubit, Locale>(
52+
'default state is [ThemeMode.light]',
53+
build: () => languageCubit,
54+
expect: () => [],
55+
verify: (_) {
56+
expect(languageCubit.state, Locale('en', 'US'));
57+
},
58+
);
59+
60+
blocTest<LanguageCubit, Locale>(
61+
'changeTheme test',
62+
build: () => languageCubit,
63+
act: (_) => languageCubit.changeLocale(Locale('az', 'AZ')),
64+
expect: () => [Locale('az', 'AZ')],
65+
);
66+
67+
tearDown(() {
68+
languageCubit.close();
69+
});
70+
},
71+
);
72+
}

test/bloc_tests/theme_cubit_test.dart

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import 'package:architecture_example/bloc/theme/theme_cubit.dart';
2+
import 'package:bloc_test/bloc_test.dart';
3+
import 'package:flutter/material.dart';
4+
import 'package:flutter_test/flutter_test.dart';
5+
6+
import '../mocks/mock_preferences_service.dart';
7+
8+
void main() {
9+
group(
10+
'ThemeCubit without default [ThemeMode]',
11+
() {
12+
late ThemeCubit themeCubit;
13+
14+
setUp(() async {
15+
themeCubit = ThemeCubit(MockPreferencesService());
16+
});
17+
18+
blocTest<ThemeCubit, ThemeMode>(
19+
'default state is [ThemeMode.system]',
20+
build: () => themeCubit,
21+
expect: () => [],
22+
verify: (_) {
23+
expect(themeCubit.state, ThemeMode.system);
24+
},
25+
);
26+
27+
blocTest<ThemeCubit, ThemeMode>(
28+
'changeTheme test',
29+
build: () => themeCubit,
30+
act: (cubit) => cubit.changeTheme(ThemeMode.dark),
31+
expect: () => [ThemeMode.dark],
32+
verify: (_) {
33+
expect(themeCubit.state, ThemeMode.dark);
34+
},
35+
);
36+
37+
tearDown(() {
38+
themeCubit.close();
39+
});
40+
},
41+
);
42+
43+
group(
44+
'ThemeCubit with default [ThemeMode]',
45+
() {
46+
late ThemeCubit themeCubit;
47+
48+
setUp(() async {
49+
final mockPreferencesService = MockPreferencesService();
50+
mockPreferencesService.changeThemeMode(ThemeMode.light);
51+
themeCubit = ThemeCubit(mockPreferencesService);
52+
});
53+
54+
blocTest<ThemeCubit, ThemeMode>(
55+
'default state is [ThemeMode.light]',
56+
build: () => themeCubit,
57+
expect: () => [],
58+
verify: (_) {
59+
expect(themeCubit.state, ThemeMode.light);
60+
},
61+
);
62+
63+
blocTest<ThemeCubit, ThemeMode>(
64+
'changeTheme test',
65+
build: () => themeCubit,
66+
act: (_) => themeCubit.changeTheme(ThemeMode.dark),
67+
expect: () => [ThemeMode.dark],
68+
);
69+
70+
tearDown(() {
71+
themeCubit.close();
72+
});
73+
},
74+
);
75+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import 'package:architecture_example/contractors/impl_preferences_service.dart';
2+
import 'package:flutter/material.dart';
3+
import 'package:flutter/src/material/app.dart';
4+
import 'package:shared_preferences/shared_preferences.dart';
5+
6+
class MockPreferencesService implements ImplPreferencesService {
7+
final _values = <String, Object>{};
8+
9+
@visibleForTesting
10+
@override
11+
Future<void> changeLocale(Locale locale) async {
12+
_values['locale'] = locale;
13+
SharedPreferences.setMockInitialValues(_values);
14+
}
15+
16+
@visibleForTesting
17+
@override
18+
Future<void> changeThemeMode(ThemeMode themeMode) async {
19+
_values['themeMode'] = themeMode.index;
20+
SharedPreferences.setMockInitialValues(_values);
21+
}
22+
23+
@visibleForTesting
24+
@override
25+
Locale? get locale {
26+
final locale = _values['locale'];
27+
28+
if (locale != null) {
29+
return locale as Locale;
30+
}
31+
32+
return null;
33+
}
34+
35+
@visibleForTesting
36+
@override
37+
ThemeMode? get themeMode {
38+
final themeMode = _values['themeMode'];
39+
40+
if (themeMode != null) {
41+
return ThemeMode.values[themeMode as int];
42+
}
43+
44+
return null;
45+
}
46+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_test/flutter_test.dart';
3+
4+
import '../mocks/mock_preferences_service.dart';
5+
6+
void main() {
7+
late MockPreferencesService? mockPreferencesService;
8+
9+
setUpAll(
10+
() {
11+
mockPreferencesService = MockPreferencesService();
12+
},
13+
);
14+
15+
test(
16+
'default values are null',
17+
() {
18+
expect(mockPreferencesService!.themeMode, isNull);
19+
expect(mockPreferencesService!.locale, isNull);
20+
},
21+
);
22+
23+
test(
24+
'themeMode insertion test',
25+
() {
26+
mockPreferencesService!.changeThemeMode(ThemeMode.dark);
27+
expect(mockPreferencesService!.themeMode, ThemeMode.dark);
28+
expect(mockPreferencesService!.locale, isNull);
29+
},
30+
);
31+
32+
test(
33+
'locale insertion test',
34+
() {
35+
mockPreferencesService!.changeLocale(Locale('en', 'US'));
36+
expect(mockPreferencesService!.themeMode, ThemeMode.dark);
37+
expect(mockPreferencesService!.locale, Locale('en', 'US'));
38+
},
39+
);
40+
41+
tearDownAll(
42+
() {
43+
mockPreferencesService = null;
44+
},
45+
);
46+
}

0 commit comments

Comments
 (0)