You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dateKeys-dart/test/pathrule_vm_test.dart

135 lines
4.8 KiB

// The rules of paths and texts against files: the copy of
// test/vectors/pathrule_vectors.json that pathrule_test.dart reads, a Dart
// constant for the tests compiled to JavaScript, is the JSON file byte for
// byte; the shared vectors of testdata/, paths.json and path_fold.json of
// datekeys-go, give their results; and every code point of every plane
// gives the results of Go, compared through the SHA-256 of one line per
// code point that tool/pathrule_go_vectors.go computes with the reference:
// here the planes that pathrule_test.dart leaves out.
@TestOn('vm')
library;
import 'dart:convert';
import 'dart:io';
import 'package:datekeys/src/bytes.dart';
import 'package:datekeys/src/pathrule.dart';
import 'package:datekeys/src/pathrule_tables.dart';
import 'package:test/test.dart';
import 'pathrule_planes.dart';
import 'vectors/pathrule_vectors.g.dart';
Map<String, Object?> readJson(String path) =>
jsonDecode(File(path).readAsStringSync()) as Map<String, Object?>;
String outcome(void Function() f) {
try {
f();
return 'ok';
} on PathRuleException catch (e) {
return e.message;
}
}
void main() {
test('pathrule_vectors.g.dart holds pathrule_vectors.json', () {
final file = File('test/vectors/pathrule_vectors.json').readAsStringSync();
expect(pathruleVectorsJson, file);
});
group('testdata', () {
final paths = readJson('testdata/vectors/paths.json');
final fold = readJson('testdata/vectors/path_fold.json');
test('name the tables of this library', () {
for (final f in [paths, fold]) {
expect(f['unicode_version'], unicodeVersion);
expect(f['tables_digest'], tablesDigest);
}
});
test('paths.json: the rules of one entry', () {
final cases = (paths['paths']! as List).cast<Map<String, Object?>>();
expect(cases, hasLength(greaterThan(80)));
for (final c in cases) {
expect(
outcome(() => checkPath(c['path']! as String)),
c['result'],
reason: c['name'] as String?,
);
}
});
test('paths.json: the paths of a head, from layer 3 to layer 4', () {
// A head checks R1 and R8 in its third layer (ERR_NON_CANONICAL_CBOR),
// comparing UTF-8 bytes, never UTF-16 code units; then each entry,
// with R2 to R10, and R7 and R9 over the tree (ERR_HEAD_INVALID).
// The decoder of the head, in stage 4c, does this with the CBOR; here
// it is done with the rules of pathrule.dart.
final trees = (paths['trees']! as List).cast<Map<String, Object?>>();
expect(trees, hasLength(greaterThan(10)));
var utf16Differs = false;
for (final c in trees) {
final name = c['name']! as String;
final list = (c['paths']! as List).cast<String>();
var result = 'ok';
var detail = '';
for (var i = 0; i < list.length && result == 'ok'; i++) {
final n = utf8Bytes(list[i]).length;
if (n < 1 ||
n > maxPathLen ||
(i > 0 &&
compareBytes(utf8Bytes(list[i - 1]), utf8Bytes(list[i])) >=
0)) {
result = 'ERR_NON_CANONICAL_CBOR';
}
if (i > 0 && list[i - 1].compareTo(list[i]) >= 0 && result == 'ok') {
utf16Differs = true;
}
}
for (var i = 0; i < list.length && result == 'ok'; i++) {
final o = outcome(() => checkPath(list[i]));
if (o != 'ok') {
result = 'ERR_HEAD_INVALID';
detail = 'file ${i + 1}: $o';
}
}
if (result == 'ok') {
final o = outcome(() => checkTree(list));
if (o != 'ok') {
result = 'ERR_HEAD_INVALID';
detail = o;
}
}
expect(result, c['result'], reason: name);
expect(detail, c['detail'] ?? '', reason: name);
}
// U+FF5E before U+1F600 is in UTF-8 order, not in UTF-16 order.
expect(utf16Differs, isTrue);
});
test('path_fold.json: the NFD and the key of R7', () {
final keys = (fold['keys']! as List).cast<Map<String, Object?>>();
expect(keys, hasLength(greaterThan(20)));
for (final c in keys) {
final s = c['segment']! as String;
expect(nfd(s), c['nfd'], reason: c['name'] as String?);
expect(pathKey(s), c['key'], reason: c['name'] as String?);
}
});
});
test('every code point of the other planes gives the results of Go', () {
// Planes 0, 1 and 14 run in pathrule_test.dart, also compiled to
// JavaScript.
final vectors = jsonDecode(pathruleVectorsJson) as Map<String, Object?>;
final planes = (vectors['planes']! as List).cast<Map<String, Object?>>();
expect(planes, hasLength(17));
for (final p in planes) {
final plane = p['plane']! as int;
if (!sharedPlanes.contains(plane)) checkPlane(plane, p);
}
});
}

Powered by TurnKey Linux.