// The cases of test/vectors/capsule_writer.json as tests: each recipe is // written again with the seeded source of its seed and the hooks that give // what Go's gave, and must draw what Go drew, ask the hooks what Go's were // asked, and write the bytes that capsule.EncryptFiles wrote, or fail with // its text and code after writing as many bytes. The capsule is then opened // by this library with each credential, as Go opened it, with the same // files, verdicts and area. capsule_writer_vm_test.dart runs them all from // the file, and capsule_writer_test.dart those marked node from the Dart // constant, also compiled to JavaScript. import 'package:datekeys/datekeys.dart'; import 'package:test/test.dart'; import 'capsule_writer_support.dart'; /// The tests of the cases of [doc]; with [allOpens] false, only the first /// opening of each capsule, which costs a verification of the round. void writerCases(Json doc, {bool allOpens = true}) { final releases = releasesOf(doc); for (final c in listOf(doc['cases'])) { final r = c['recipe']! as Json; test(r['name'], () async { final w = await writeRecipe(r, c['hooks'] as Json? ?? const {}); expect(w.draws, c['draws'], reason: 'the draws'); expect(w.asked, c['hooks'] ?? const {}, reason: 'the hooks'); final e = c['error'] as Json?; if (e != null) { final err = w.error; expect(err, isNotNull, reason: 'Go fails with ${e['text']}'); expect(errorText(err!), e['text']); expect(writerCode(err), e['code']); expect(w.dkc.length, e['written'], reason: 'the bytes written'); expect(w.sink.aborted, same(err)); expect(w.sink.closed, isFalse); return; } expect(w.error, isNull); final g = c['written']! as Json; final res = w.result!; final header = hexOf(g['header']); expect(toHex(w.dkc.sublist(16, 16 + header.length)), g['header']); expect(w.dkc.length, g['length_dkc']); expect(toHex(sha256Of(w.dkc)), g['sha256']); if (g['dkc'] != null) expect(toHex(w.dkc), g['dkc']); expect(w.sink.closed, isTrue); expect(w.sink.aborted, isNull); expect(res.dateKey.round, g['round']); expect(res.unlockAt.toString(), g['unlock_at']); expect(toHex(res.capsuleId), g['capsule_id']); expect(res.length, g['length']); expect(res.padding.code, g['padding']); expect(res.paddedLength, g['padded_length']); expect(toHex(encodeHead(res.head)), g['head']); final k = res.portableKey; expect(k == null ? null : toHex(encodeAccessKey(k)), g['dkk']); expect(g['reencoded'], isTrue); final want = listOf(c['opens']); final got = await opensOf( r, w.dkc, releases, res.dateKey.round, res.capsuleId, k == null ? null : encodeAccessKey(k), limit: allOpens ? null : 1, ); expect(got, want.sublist(0, got.length)); }); } }