test/models: test json serialization roundtrips for all models
Build and test / build (push) Successful in 5m17s
Build and test / build (push) Successful in 5m17s
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:jadb/models/kanji_search/kanji_search_radical.dart';
|
||||
import 'package:jadb/models/kanji_search/kanji_search_result.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);
|
||||
|
||||
void main() {
|
||||
test('KanjiSearchRadical JSON serialization roundtrip', () {
|
||||
const radical = KanjiSearchRadical(
|
||||
symbol: '人',
|
||||
names: ['ひと', 'にんべん'],
|
||||
forms: ['亻'],
|
||||
meanings: ['person', 'human'],
|
||||
);
|
||||
|
||||
final restored = KanjiSearchRadical.fromJson(
|
||||
_roundTripMap(radical.toJson()),
|
||||
);
|
||||
|
||||
expect(restored, equals(radical));
|
||||
});
|
||||
|
||||
test('KanjiSearchResult JSON serialization roundtrip', () {
|
||||
const result = KanjiSearchResult(
|
||||
kanji: '休',
|
||||
taughtIn: 1,
|
||||
jlptLevel: 'N5',
|
||||
newspaperFrequencyRank: 1234,
|
||||
strokeCount: 6,
|
||||
meanings: ['rest', 'day off'],
|
||||
kunyomi: ['やす.む', 'やす.まる'],
|
||||
onyomi: ['キュウ'],
|
||||
radical: KanjiSearchRadical(
|
||||
symbol: '人',
|
||||
names: ['ひと', 'にんべん'],
|
||||
forms: ['亻'],
|
||||
meanings: ['person', 'human'],
|
||||
),
|
||||
parts: ['亻', '木'],
|
||||
codepoints: {'ucs': '4F11', 'jis208': '1-22-57'},
|
||||
nanori: ['やす'],
|
||||
alternativeLanguageReadings: {
|
||||
'korean': ['휴'],
|
||||
'pinyin': ['xiū'],
|
||||
},
|
||||
strokeMiscounts: [5, 7],
|
||||
queryCodes: {
|
||||
'skip': ['1-2-4'],
|
||||
'fourCorner': ['2429.0'],
|
||||
},
|
||||
dictionaryReferences: {'nelson_c': '122', 'heisig': '457'},
|
||||
);
|
||||
|
||||
final restored = KanjiSearchResult.fromJson(_roundTripMap(result.toJson()));
|
||||
|
||||
expect(restored, equals(result));
|
||||
});
|
||||
|
||||
test(
|
||||
'KanjiSearchResult JSON serialization roundtrip - nullable and empty fields',
|
||||
() {
|
||||
const result = KanjiSearchResult(
|
||||
kanji: '々',
|
||||
taughtIn: null,
|
||||
jlptLevel: null,
|
||||
newspaperFrequencyRank: null,
|
||||
strokeCount: 3,
|
||||
meanings: ['iteration mark'],
|
||||
kunyomi: [],
|
||||
onyomi: [],
|
||||
radical: null,
|
||||
parts: [],
|
||||
codepoints: {'ucs': '3005'},
|
||||
nanori: [],
|
||||
alternativeLanguageReadings: {},
|
||||
strokeMiscounts: [],
|
||||
queryCodes: {},
|
||||
dictionaryReferences: {},
|
||||
);
|
||||
|
||||
final restored = KanjiSearchResult.fromJson(
|
||||
_roundTripMap(result.toJson()),
|
||||
);
|
||||
|
||||
expect(restored, equals(result));
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
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()));
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user