frindlymap/test/kinship_test.dart

188 lines
7.1 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:friendly_map/modules/kinship/kinship.dart';
const M = Gender.male, F = Gender.female;
/// 시험용 가족. 나(남, 1990)와 아내, 아들, 양가 친척.
KinGraph family() {
final g = KinGraph();
void p(String id, Gender gen, int year) => g.put(KinPerson(id, gender: gen, birthYear: year));
p('me', M, 1990);
p('father', M, 1960);
p('mother', F, 1962);
p('gf', M, 1930); // 친할아버지
p('gm', F, 1932); // 친할머니
p('mgm', F, 1935); // 외할머니
p('bigUncle', M, 1955); // 아버지의 형
p('bigAunt', F, 1957); // 큰아버지의 아내
p('aunt', F, 1965); // 아버지의 여동생(고모)
p('mUncle', M, 1964); // 어머니의 남동생(외삼촌)
p('mAunt', F, 1966); // 이모
p('cousinElder', M, 1985); // 큰아버지의 아들
p('cousinGojong', F, 1992); // 고모의 딸
p('cousinOe', M, 1995); // 외삼촌의 아들
p('sister', F, 1993);
p('wife', F, 1991);
p('wifeFather', M, 1962);
p('wifeSister', F, 1994);
p('son', M, 2020);
p('daughterInLaw', F, 1990);
p('grandson', M, 2045);
for (final c in ['father', 'bigUncle', 'aunt']) {
g.addParent(c, 'gf');
}
g.addParent('father', 'gm');
g.addParent('bigUncle', 'gm');
g.addParent('aunt', 'gm');
g.addParent('mother', 'mgm');
g.addParent('mUncle', 'mgm');
g.addParent('mAunt', 'mgm');
g.addParent('me', 'father');
g.addParent('me', 'mother');
g.addParent('sister', 'father');
g.addParent('sister', 'mother');
g.addParent('cousinElder', 'bigUncle');
g.addParent('cousinGojong', 'aunt');
g.addParent('cousinOe', 'mUncle');
g.addParent('wife', 'wifeFather');
g.addParent('wifeSister', 'wifeFather');
g.addParent('son', 'me');
g.addParent('son', 'wife');
g.addParent('grandson', 'son');
g.addSpouse('me', 'wife');
g.addSpouse('father', 'mother');
g.addSpouse('gf', 'gm');
g.addSpouse('bigUncle', 'bigAunt');
g.addSpouse('son', 'daughterInLaw');
return g;
}
String t(KinGraph g, String a, String b) => relate(g, a, b).title;
int? c(KinGraph g, String a, String b) => relate(g, a, b).chon;
void main() {
final g = family();
group('직계', () {
test('부모·자녀 1촌, 조부모·손주 2촌', () {
expect((t(g, 'me', 'father'), c(g, 'me', 'father')), ('아버지', 1));
expect((t(g, 'me', 'mother'), c(g, 'me', 'mother')), ('어머니', 1));
expect((t(g, 'me', 'son'), c(g, 'me', 'son')), ('아들', 1));
expect((t(g, 'me', 'gf'), c(g, 'me', 'gf')), ('친할아버지', 2));
expect(t(g, 'me', 'mgm'), '외할머니');
expect((t(g, 'me', 'grandson'), c(g, 'me', 'grandson')), ('손자', 2));
});
test('거꾸로도 맞다: 아들 입장에서 나는 아버지', () {
expect(t(g, 'son', 'me'), '아버지');
expect(t(g, 'grandson', 'gf'), '고조할아버지'); // 손자 → 아들 → 나 → 아버지 → 할아버지: 4대 위
expect(t(g, 'son', 'gf'), '증조할아버지');
});
});
group('형제와 방계', () {
test('형제자매는 2촌, 나이로 형·동생 구분', () {
expect((t(g, 'me', 'sister'), c(g, 'me', 'sister')), ('여동생', 2));
expect(t(g, 'sister', 'me'), '오빠');
});
test('아버지 쪽 삼촌: 큰아버지·고모, 어머니 쪽: 외삼촌·이모 (모두 3촌)', () {
expect((t(g, 'me', 'bigUncle'), c(g, 'me', 'bigUncle')), ('큰아버지', 3));
expect(t(g, 'me', 'aunt'), '고모');
expect(t(g, 'me', 'mUncle'), '외삼촌');
expect(t(g, 'me', 'mAunt'), '이모');
});
test('사촌은 4촌: 친사촌·고종사촌·외사촌, 나이에 따라 형·동생', () {
expect((t(g, 'me', 'cousinElder'), c(g, 'me', 'cousinElder')), ('친사촌 형', 4));
expect(t(g, 'me', 'cousinGojong'), '고종사촌 여동생');
expect(t(g, 'me', 'cousinOe'), '외사촌 남동생');
});
test('내 아들 입장: 아버지의 사촌은 당숙(5촌), 큰아버지는 4촌 할아버지 항렬이 아니라 5촌이 아님을 구분', () {
expect((t(g, 'son', 'cousinElder'), c(g, 'son', 'cousinElder')), ('당숙', 5));
expect(c(g, 'son', 'bigUncle'), 4);
expect(c(g, 'son', 'sister'), 3); // 고모
expect(t(g, 'son', 'sister'), '고모');
});
test('조카: 나의 형제의 자녀는 3촌', () {
final g2 = family();
g2.put(const KinPerson('nephew', gender: Gender.male, birthYear: 2018));
g2.addParent('nephew', 'sister');
expect((t(g2, 'me', 'nephew'), c(g2, 'me', 'nephew')), ('조카', 3));
});
});
group('인척', () {
test('배우자 0촌, 며느리·사위 1촌', () {
expect((t(g, 'me', 'wife'), c(g, 'me', 'wife')), ('아내', 0));
expect(t(g, 'wife', 'me'), '남편');
expect((t(g, 'me', 'daughterInLaw'), c(g, 'me', 'daughterInLaw')), ('며느리', 1));
});
test('아내의 부모는 장인, 아내의 동생은 처제', () {
expect((t(g, 'me', 'wifeFather'), c(g, 'me', 'wifeFather')), ('장인', 1));
expect(t(g, 'me', 'wifeSister'), '처제');
expect(t(g, 'wife', 'father'), '시아버지');
});
test('큰아버지의 아내는 큰어머니(3촌)', () {
expect((t(g, 'me', 'bigAunt'), c(g, 'me', 'bigAunt')), ('큰어머니', 3));
});
test('모르는 사이는 none', () {
g.put(const KinPerson('stranger'));
final r = relate(g, 'me', 'stranger');
expect(r.related, false);
expect(r.chon, null);
});
});
group('이름표·가계도 관리', () {
test('label 은 촌수까지 읽기 좋게', () {
expect(relate(g, 'me', 'bigUncle').label, '큰아버지 (3촌)');
expect(relate(g, 'me', 'wife').label, '아내');
expect(relate(g, 'me', 'me').label, '본인');
});
test('나이를 모르면 형·동생 대신 형제', () {
final g3 = KinGraph();
g3.put(const KinPerson('me', gender: M));
g3.put(const KinPerson('x', gender: M));
g3.put(const KinPerson('p', gender: M));
g3.addParent('me', 'p');
g3.addParent('x', 'p');
expect(t(g3, 'me', 'x'), '형제');
});
test('부모 순환·셋째 부모는 거절', () {
final g4 = KinGraph();
for (final id in ['a', 'b', 'c', 'd']) {
g4.put(KinPerson(id));
}
expect(g4.addParent('a', 'b'), true);
expect(g4.addParent('b', 'a'), false); // 순환
expect(g4.addParent('a', 'c'), true);
expect(g4.addParent('a', 'd'), false); // 부모는 최대 둘
expect(g4.addParent('a', 'a'), false);
});
test('글자로 저장했다 복원하면 같은 계산, 깨진 글자는 빈 가계도', () {
final back = KinGraph.fromJson(g.toJson());
expect(t(back, 'me', 'bigUncle'), '큰아버지');
expect(t(back, 'me', 'wifeFather'), '장인');
expect(KinGraph.fromJson('{깨짐').people, isEmpty);
expect(KinGraph.fromJson(null).people, isEmpty);
});
test('사람을 지우면 연결도 사라진다', () {
final g5 = KinGraph.fromJson(g.toJson());
g5.removePerson('father');
expect(g5.has('father'), false);
expect(g5.parentsOf('me').contains('father'), false);
expect(relate(g5, 'me', 'bigUncle').related, false);
});
});
}