// The mutation corpus of spec ยง64, testdata/vectors/mutations.json, through // the opening, as internal/testkit of the reference replays it: the code // and the step of the corpus, and the text and the checks that capsule.Open // of Go gives on each case (test/vectors/mutation_texts.json, which // tool/mutation_go_texts.go writes), in memory and from a source read in // pieces; the verdicts and their lines of each case that opens; no release // request for a case that fails without the network; and every case whose // step is 1 to 8 through the inspection too. @TestOn('vm') library; import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; import 'package:datekeys/datekeys.dart'; import 'package:test/test.dart'; import 'open_support.dart'; Json readJson(String path) => jsonDecode(File(path).readAsStringSync()) as Json; final _fixtures = {}; Uint8List fixture(String file) => _fixtures.putIfAbsent( file, () => File('testdata/fixtures/$file').readAsBytesSync(), ); void main() { final corpus = readJson('testdata/vectors/mutations.json'); final cases = (corpus['cases']! as List).cast(); final texts = readJson('test/vectors/mutation_texts.json'); final goCases = (texts['cases']! as List).cast(); test('has the cases of README, with the text of Go for each', () { expect(corpus['spec'], specVersion); expect(texts['spec'], specVersion); expect(texts['generator'], 'tool/mutation_go_texts.go'); expect(cases, hasLength(218)); expect( [for (final c in goCases) c['name']], [for (final c in cases) c['name']], ); // Go at c531e93 and the corpus of the draft v0.12 agree on every case. expect(goCases.where((c) => c.containsKey('go_error')), isEmpty); expect(cases.where((c) => c['spec'] == true), hasLength(178)); expect(cases.where((c) => c['error'] == 'ok'), hasLength(11)); expect( cases.where((c) => c['error'] != 'ok' && (c['step']! as int) <= 8), hasLength(57), ); }); for (var i = 0; i < cases.length; i++) { final c = cases[i]; final go = goCases[i]; test('#$i ${c['name']} (step ${c['step']})', () async { final dkc = capsuleOf(c, fixture); for (final fromSource in [false, true]) { final o = await openCase(c, dkc, fromSource: fromSource); final where = fromSource ? 'from a source' : 'in memory'; expect(o.result, c['error'], reason: where); expect(o.text, go['text'], reason: where); expect(canonical(o.checks), canonical(go['checks']), reason: where); final last = o.opened.checks.last; if (c['error'] == 'ok') { // The cases of security that open, with the verdicts of the // corpus and their lines; none needs the reader of CMS. expect([last.step, last.ok], [18, true], reason: where); final security = o.securities.single; expect(cmsParts(security), (signature: false, seal: false)); expect( verdictDifferences( c['verdicts']! as Json, o.opened.verdicts!, keys: false, ), isEmpty, reason: where, ); expect(o.sink.state, 'committed'); } else { expect([last.step, last.ok], [c['step'], false], reason: where); expect(o.output.closed, isFalse); expect(o.output.aborted, isNotNull); expect(o.sink.state, anyOf('untouched', 'aborted')); } if (c['network'] == false) { expect(o.calls, 0, reason: 'no release request without the network'); } } if (c['error'] != 'ok' && (c['step']! as int) <= 8) { final r = inspectCapsule( dkc, registry: c['registry'] == 'empty' ? newRegistry([]) : null, extensions: caseExtensions(c), ); expect( [r.error?.code.code, r.checks.last.step], [c['error'], c['step']], ); expect(r.error!.message, go['text']); } }); } }