283 lines
8.2 KiB
Dart
283 lines
8.2 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:jadb/models/common/jlpt_level.dart';
|
|
import 'package:jadb/models/jmdict/jmdict_dialect.dart';
|
|
import 'package:jadb/models/jmdict/jmdict_field.dart';
|
|
import 'package:jadb/models/jmdict/jmdict_kanji_info.dart';
|
|
import 'package:jadb/models/jmdict/jmdict_misc.dart';
|
|
import 'package:jadb/models/jmdict/jmdict_pos.dart';
|
|
import 'package:jadb/models/jmdict/jmdict_reading_info.dart';
|
|
import 'package:jadb/models/word_search/word_search_match_span.dart';
|
|
import 'package:jadb/models/word_search/word_search_result.dart';
|
|
import 'package:jadb/models/word_search/word_search_ruby.dart';
|
|
import 'package:jadb/models/word_search/word_search_sense.dart';
|
|
import 'package:jadb/models/word_search/word_search_sense_language_source.dart';
|
|
import 'package:jadb/models/word_search/word_search_sources.dart';
|
|
import 'package:jadb/models/word_search/word_search_xref_entry.dart';
|
|
import 'package:test/test.dart';
|
|
|
|
Object? _roundTripJson(Object? value) => jsonDecode(jsonEncode(value));
|
|
|
|
Map<String, dynamic> _roundTripMap(Object? json) =>
|
|
Map<String, dynamic>.from(_roundTripJson(json) as Map);
|
|
|
|
Map<String, Object?> _roundTripObjectMap(Object? json) =>
|
|
Map<String, Object?>.from(_roundTripJson(json) as Map);
|
|
|
|
void _expectScalarRoundTrip<T>({
|
|
required Iterable<T> values,
|
|
required Object? Function(T value) toJson,
|
|
required T Function(Object? json) fromJson,
|
|
}) {
|
|
for (final value in values) {
|
|
expect(
|
|
fromJson(_roundTripJson(toJson(value))),
|
|
equals(value),
|
|
reason: 'Roundtrip failed for $value',
|
|
);
|
|
}
|
|
}
|
|
|
|
void _expectMapRoundTrip<T>({
|
|
required Iterable<T> values,
|
|
required Map<String, Object?> Function(T value) toJson,
|
|
required T Function(Map<String, Object?> json) fromJson,
|
|
}) {
|
|
for (final value in values) {
|
|
expect(
|
|
fromJson(_roundTripObjectMap(toJson(value))),
|
|
equals(value),
|
|
reason: 'Roundtrip failed for $value',
|
|
);
|
|
}
|
|
}
|
|
|
|
WordSearchResult _buildNestedXrefResult() => WordSearchResult(
|
|
score: 7,
|
|
entryId: 300,
|
|
isCommon: false,
|
|
japanese: [WordSearchRuby(base: '補助', furigana: 'ほじょ')],
|
|
kanjiInfo: const {},
|
|
readingInfo: const {},
|
|
senses: const [],
|
|
jlptLevel: JlptLevel.none,
|
|
sources: const WordSearchSources(jmdict: true, jmnedict: false),
|
|
);
|
|
|
|
WordSearchSense _buildSense() => WordSearchSense(
|
|
englishDefinitions: ['kana', 'syllabary'],
|
|
partsOfSpeech: [JMdictPOS.n],
|
|
seeAlso: [
|
|
WordSearchXrefEntry(
|
|
entryId: 300,
|
|
ambiguous: false,
|
|
baseWord: '仮名遣い',
|
|
furigana: 'かなづかい',
|
|
xrefResult: _buildNestedXrefResult(),
|
|
),
|
|
],
|
|
antonyms: const [
|
|
WordSearchXrefEntry(
|
|
entryId: 301,
|
|
ambiguous: true,
|
|
baseWord: '漢字',
|
|
furigana: 'かんじ',
|
|
xrefResult: null,
|
|
),
|
|
],
|
|
restrictedToReading: ['かな'],
|
|
restrictedToKanji: ['仮名'],
|
|
fields: [JMdictField.linguistics],
|
|
dialects: [JMdictDialect.kansai],
|
|
misc: [JMdictMisc.onlyKana, JMdictMisc.rare],
|
|
info: ['Typically written using kana alone.'],
|
|
languageSource: const [
|
|
WordSearchSenseLanguageSource(
|
|
language: 'por',
|
|
phrase: 'canoa',
|
|
fullyDescribesSense: false,
|
|
constructedFromSmallerWords: true,
|
|
),
|
|
],
|
|
);
|
|
|
|
WordSearchResult _buildWordSearchResult({
|
|
List<WordSearchMatchSpan>? matchSpans,
|
|
}) => WordSearchResult(
|
|
score: 42,
|
|
entryId: 123,
|
|
isCommon: true,
|
|
japanese: [
|
|
WordSearchRuby(base: '仮名', furigana: 'かな'),
|
|
WordSearchRuby(base: 'かな'),
|
|
],
|
|
kanjiInfo: {'仮名': JMdictKanjiInfo.rK, '仮': JMdictKanjiInfo.ateji},
|
|
readingInfo: {'かな': JMdictReadingInfo.gikun, 'カナ': JMdictReadingInfo.rk},
|
|
senses: [_buildSense()],
|
|
jlptLevel: JlptLevel.n5,
|
|
sources: const WordSearchSources(jmdict: true, jmnedict: true),
|
|
matchSpans: matchSpans,
|
|
);
|
|
|
|
void main() {
|
|
test('JlptLevel JSON serialization roundtrip', () {
|
|
_expectScalarRoundTrip<JlptLevel>(
|
|
values: JlptLevel.values,
|
|
toJson: (value) => value.toJson(),
|
|
fromJson: JlptLevel.fromJson,
|
|
);
|
|
});
|
|
|
|
test('JMdictDialect JSON serialization roundtrip', () {
|
|
_expectMapRoundTrip<JMdictDialect>(
|
|
values: JMdictDialect.values,
|
|
toJson: (value) => value.toJson(),
|
|
fromJson: JMdictDialect.fromJson,
|
|
);
|
|
});
|
|
|
|
test('JMdictField JSON serialization roundtrip', () {
|
|
_expectMapRoundTrip<JMdictField>(
|
|
values: JMdictField.values,
|
|
toJson: (value) => value.toJson(),
|
|
fromJson: JMdictField.fromJson,
|
|
);
|
|
});
|
|
|
|
test('JMdictKanjiInfo JSON serialization roundtrip', () {
|
|
_expectMapRoundTrip<JMdictKanjiInfo>(
|
|
values: JMdictKanjiInfo.values,
|
|
toJson: (value) => value.toJson(),
|
|
fromJson: JMdictKanjiInfo.fromJson,
|
|
);
|
|
});
|
|
|
|
test('JMdictMisc JSON serialization roundtrip', () {
|
|
_expectMapRoundTrip<JMdictMisc>(
|
|
values: JMdictMisc.values,
|
|
toJson: (value) => value.toJson(),
|
|
fromJson: JMdictMisc.fromJson,
|
|
);
|
|
});
|
|
|
|
test('JMdictPOS JSON serialization roundtrip', () {
|
|
_expectMapRoundTrip<JMdictPOS>(
|
|
values: JMdictPOS.values,
|
|
toJson: (value) => value.toJson(),
|
|
fromJson: JMdictPOS.fromJson,
|
|
);
|
|
});
|
|
|
|
test('JMdictReadingInfo JSON serialization roundtrip', () {
|
|
_expectMapRoundTrip<JMdictReadingInfo>(
|
|
values: JMdictReadingInfo.values,
|
|
toJson: (value) => value.toJson(),
|
|
fromJson: JMdictReadingInfo.fromJson,
|
|
);
|
|
});
|
|
|
|
test('WordSearchMatchSpan JSON serialization roundtrip', () {
|
|
final span = WordSearchMatchSpan(
|
|
spanType: WordSearchMatchSpanType.sense,
|
|
index: 2,
|
|
subIndex: 3,
|
|
start: 4,
|
|
end: 8,
|
|
);
|
|
|
|
final restored = WordSearchMatchSpan.fromJson(_roundTripMap(span.toJson()));
|
|
|
|
expect(restored, equals(span));
|
|
expect(restored.subIndex, equals(span.subIndex));
|
|
});
|
|
|
|
test('WordSearchRuby JSON serialization roundtrip', () {
|
|
final ruby = WordSearchRuby(base: '仮名', furigana: 'かな');
|
|
|
|
final restored = WordSearchRuby.fromJson(_roundTripMap(ruby.toJson()));
|
|
|
|
expect(restored.toJson(), equals(ruby.toJson()));
|
|
});
|
|
|
|
test('WordSearchSenseLanguageSource JSON serialization roundtrip', () {
|
|
const source = WordSearchSenseLanguageSource(
|
|
language: 'por',
|
|
phrase: 'canoa',
|
|
fullyDescribesSense: false,
|
|
constructedFromSmallerWords: true,
|
|
);
|
|
|
|
final restored = WordSearchSenseLanguageSource.fromJson(
|
|
_roundTripMap(source.toJson()),
|
|
);
|
|
|
|
expect(restored.toJson(), equals(source.toJson()));
|
|
});
|
|
|
|
test('WordSearchSources JSON serialization roundtrip', () {
|
|
const sources = WordSearchSources(jmdict: false, jmnedict: true);
|
|
|
|
final restored = WordSearchSources.fromJson(
|
|
_roundTripMap(sources.toJson()),
|
|
);
|
|
|
|
expect(restored.toJson(), equals(sources.toJson()));
|
|
expect(restored.sqlValue, equals(sources.sqlValue));
|
|
});
|
|
|
|
test('WordSearchXrefEntry JSON serialization roundtrip', () {
|
|
final entry = WordSearchXrefEntry(
|
|
entryId: 300,
|
|
ambiguous: false,
|
|
baseWord: '仮名遣い',
|
|
furigana: 'かなづかい',
|
|
xrefResult: _buildNestedXrefResult(),
|
|
);
|
|
|
|
final restored = WordSearchXrefEntry.fromJson(
|
|
_roundTripMap(entry.toJson()),
|
|
);
|
|
|
|
expect(restored.toJson(), equals(entry.toJson()));
|
|
expect(restored.xrefResult?.toJson(), equals(entry.xrefResult?.toJson()));
|
|
});
|
|
|
|
test('WordSearchSense JSON serialization roundtrip', () {
|
|
final sense = _buildSense();
|
|
|
|
final restored = WordSearchSense.fromJson(_roundTripMap(sense.toJson()));
|
|
|
|
expect(restored.toJson(), equals(sense.toJson()));
|
|
});
|
|
|
|
test('WordSearchResult JSON serialization roundtrip', () {
|
|
final result = _buildWordSearchResult();
|
|
|
|
final restored = WordSearchResult.fromJson(_roundTripMap(result.toJson()));
|
|
|
|
expect(restored.toJson(), equals(result.toJson()));
|
|
expect(restored.matchSpans, isNull);
|
|
});
|
|
|
|
test('WordSearchResult leaves matchSpans out of JSON', () {
|
|
final result = _buildWordSearchResult(
|
|
matchSpans: [
|
|
WordSearchMatchSpan(
|
|
spanType: WordSearchMatchSpanType.sense,
|
|
index: 0,
|
|
subIndex: 1,
|
|
start: 0,
|
|
end: 4,
|
|
),
|
|
],
|
|
);
|
|
|
|
final json = _roundTripMap(result.toJson());
|
|
final restored = WordSearchResult.fromJson(json);
|
|
|
|
expect(json.containsKey('matchSpans'), isFalse);
|
|
expect(restored.matchSpans, isNull);
|
|
expect(restored.toJson(), equals(result.toJson()));
|
|
});
|
|
}
|