// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. library trydart.test.program_result; import 'dart:convert' show JSON; import '../poi/source_update.dart'; class ProgramResult { final /* Map or String */ code; final List messages; final bool compileUpdatesShouldThrow; const ProgramResult( this.code, this.messages, {this.compileUpdatesShouldThrow: false}); List messagesWith(String extra) { return new List.from(messages)..add(extra); } String toString() { return """ ProgramResult( ${JSON.encode(code)}, ${JSON.encode(messages)}, compileUpdatesShouldThrow: $compileUpdatesShouldThrow)"""; } } class ProgramExpectation { final List messages; final bool compileUpdatesShouldThrow; const ProgramExpectation( this.messages, {this.compileUpdatesShouldThrow: false}); ProgramResult toResult(String code) { return new ProgramResult( code, messages, compileUpdatesShouldThrow: compileUpdatesShouldThrow); } } class EncodedResult { final /* String or List */ updates; final List expectations; const EncodedResult(this.updates, this.expectations); List decode() { if (updates is List) { if (updates.length == 1) { throw new StateError("Trivial diff, no reason to use decode."); } List sources = expandUpdates(updates); if (sources.length != expectations.length) { throw new StateError( "Number of sources and expectations differ" " (${sources.length} sources," " ${expectations.length} expectations)."); } List result = new List(sources.length); for (int i = 0; i < sources.length; i++) { result[i] = expectations[i].toResult(sources[i]); } return result; } else if (updates is String) { Map files = splitFiles(updates); Map> fileMap = >{}; int updateCount = -1; for (String name in files.keys) { if (name.endsWith(".patch")) { String realname = name.substring(0, name.length - ".patch".length); if (files.containsKey(realname)) { throw new StateError("Patch '$name' conflicts with '$realname'"); } if (fileMap.containsKey(realname)) { // Can't happen. throw new StateError("Duplicated entry for '$realname'."); } List updates = expandUpdates(expandDiff(files[name])); if (updates.length == 1) { throw new StateError("No patches found in:\n ${files[name]}"); } if (updateCount == -1) { updateCount = updates.length; } else if (updateCount != updates.length) { throw new StateError( "Unexpected number of patches: ${updates.length}," " expected ${updateCount}"); } fileMap[realname] = updates; } } if (updateCount == -1) { throw new StateError("No patch files in $updates"); } for (String name in files.keys) { if (!name.endsWith(".patch")) { fileMap[name] = new List.filled(updateCount, files[name]); } } if (updateCount != expectations.length) { throw new StateError( "Number of patches and expectations differ " "(${updateCount} patches, ${expectations.length} expectations)."); } List result = new List(updateCount); for (int i = 0; i < updateCount; i++) { ProgramExpectation expectation = decodeExpectation(expectations[i]); result[i] = new ProgramResult( {}, expectation.messages, compileUpdatesShouldThrow: expectation.compileUpdatesShouldThrow); } for (String name in fileMap.keys) { for (int i = 0; i < updateCount; i++) { result[i].code[name] = fileMap[name][i]; } } return result; } else { throw new StateError("Unknown encoding of updates"); } } } ProgramExpectation decodeExpectation(expectation) { if (expectation is ProgramExpectation) { return expectation; } else if (expectation is String) { return new ProgramExpectation([expectation]); } else if (expectation is List) { return new ProgramExpectation(new List.from(expectation)); } else { throw new ArgumentError("Don't know how to decode $expectation"); } }