Skip to content

Commit

Permalink
refactor(search_condition): ♻️ move highlightedRange as method (#51)
Browse files Browse the repository at this point in the history
* refactor(search_condition): ♻️ move `highlightedRange` as method

* docs(search_condition): 📖 add more examples for `highlightedRange`

* test(main): 🧪 add `search_condition_test`
  • Loading branch information
albertms10 authored Feb 4, 2024
1 parent 917c115 commit 8707377
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 16 deletions.
38 changes: 38 additions & 0 deletions lib/src/model/search_condition.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'package:diacritic/diacritic.dart';

enum SearchCondition {
coincident,
startingWith,
Expand All @@ -9,6 +11,42 @@ enum SearchCondition {

static const defaultCondition = startingWith;

/// Returns the highlighted range for [query] in [word] based on this
/// [SearchCondition].
///
/// Example:
/// ```dart
/// SearchCondition.startingWith.highlightedRange('pla', 'pl') == (0, 2)
/// SearchCondition.endingIn.highlightedRange('alçària', 'aria') == (3, 7)
/// SearchCondition.doesNotContain.highlightedRange('alçària', 'b') == null
/// ```
(int start, int end)? highlightedRange(String word, String query) {
switch (this) {
case coincident:
return (0, word.length);

case endingIn:
var lastIndex = word.lastIndexOf(query);
if (lastIndex == -1) {
lastIndex =
removeDiacritics(word).lastIndexOf(removeDiacritics(query));
}
if (lastIndex == -1) return null;
return (lastIndex, lastIndex + query.length);

case startingWith || inAnyPosition:
var index = word.indexOf(query);
if (index == -1) {
index = removeDiacritics(word).indexOf(removeDiacritics(query));
}
if (index == -1) return null;
return (index, index + query.length);

default:
return null;
}
}

String translate() => switch (this) {
coincident => 'Coincident',
startingWith => 'Començada per',
Expand Down
18 changes: 2 additions & 16 deletions lib/src/widgets/autocomplete_entry_card.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'package:diacritic/diacritic.dart';
import 'package:el_meu_diec/model.dart';
import 'package:el_meu_diec/src/constants.dart';
import 'package:el_meu_diec/src/pages/word_page.dart';
Expand All @@ -25,26 +24,13 @@ class AutocompleteEntryCard extends StatelessWidget {

bool get isIncomplete => word.word.length > query.length;

(int start, int end) get highlightedRange => switch (searchCondition) {
SearchCondition.startingWith => (0, query.length),
SearchCondition.endingIn => (
word.word.length - query.length,
word.word.length,
),
SearchCondition.inAnyPosition => (
removeDiacritics(word.word).indexOf(removeDiacritics(query)),
removeDiacritics(word.word).indexOf(removeDiacritics(query)) +
query.length,
),
_ => (0, word.word.length),
};

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final headlineTextStyle = theme.textTheme.headlineTextStyle;

final (start, end) = highlightedRange;
final (start, end) = searchCondition.highlightedRange(word.word, query) ??
(0, word.word.length);
final isIncompleteStart = start > 0;
final isIncompleteEnd = end < word.word.length;

Expand Down
2 changes: 2 additions & 0 deletions test/main.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import 'model/definition_entry_sense_test.dart' as definition_entry_sense_test;
import 'model/gender_test.dart' as gender_test;
import 'model/scope_test.dart' as scope_test;
import 'model/search_condition_test.dart' as search_condition_test;

void main() {
definition_entry_sense_test.main();
gender_test.main();
scope_test.main();
search_condition_test.main();
}
61 changes: 61 additions & 0 deletions test/model/search_condition_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import 'package:el_meu_diec/model.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
group('SearchCondition', () {
group('.highlightedRange()', () {
test('should return the highlighted range in word from query', () {
expect(
SearchCondition.coincident.highlightedRange('dart', 'a'),
const (0, 4),
);

expect(
SearchCondition.startingWith.highlightedRange('dart', 'd'),
const (0, 1),
);
expect(
SearchCondition.startingWith.highlightedRange('alçària', 'alça'),
const (0, 4),
);

expect(
SearchCondition.endingIn.highlightedRange('dart', 'rt'),
const (2, 4),
);
expect(
SearchCondition.endingIn.highlightedRange('dart2', 't'),
const (3, 4),
);
expect(
SearchCondition.endingIn.highlightedRange('fabària', 'aria'),
const (3, 7),
);

expect(
SearchCondition.inAnyPosition.highlightedRange('dart', 'a'),
const (1, 2),
);
});

test('should return null when no range to highlight is found', () {
expect(
SearchCondition.startingWith.highlightedRange('dart', 'c'),
isNull,
);
expect(
SearchCondition.notStartingWith.highlightedRange('dart', 'f'),
isNull,
);
expect(
SearchCondition.notEndingIn.highlightedRange('dart', 'f'),
isNull,
);
expect(
SearchCondition.doesNotContain.highlightedRange('dart', 'f'),
isNull,
);
});
});
});
}

0 comments on commit 8707377

Please sign in to comment.