OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library descriptor.file; | |
6 | |
7 import 'dart:async'; | |
8 import 'dart:io' as io; | |
9 import 'dart:math' as math; | |
10 import 'dart:utf'; | |
11 | |
12 import 'package:pathos/path.dart' as path; | |
13 | |
14 import '../../descriptor.dart' as descriptor; | |
15 import '../../scheduled_test.dart'; | |
16 import '../utils.dart'; | |
17 import 'utils.dart'; | |
18 | |
19 /// A descriptor describing a single file. | |
20 class File extends descriptor.Entry { | |
21 /// Whether this descriptor describes a binary file. This is only used when | |
22 /// displaying error messages. | |
23 final bool isBinary; | |
24 | |
25 /// The contents of the file, in bytes. | |
26 final List<int> contents; | |
27 | |
28 /// The contents of the file as a String. Assumes UTF-8 encoding. | |
29 String get textContents => new String.fromCharCodes(contents); | |
30 | |
31 File.binary(Pattern name, List<int> contents) | |
32 : this._(name, contents, true); | |
33 | |
34 File(Pattern name, String contents) | |
35 : this._(name, encodeUtf8(contents), false); | |
36 | |
37 File._(Pattern name, this.contents, this.isBinary) | |
38 : super(name); | |
39 | |
40 Future create([String parent]) => schedule(() { | |
41 if (parent == null) parent = descriptor.defaultRoot; | |
42 return new io.File(path.join(parent, stringName)).writeAsBytes(contents); | |
43 }, 'creating file $nameDescription'); | |
44 | |
45 Future validate([String parent]) => schedule(() { | |
46 if (parent == null) parent = descriptor.defaultRoot; | |
47 var fullPath = entryMatchingPattern('File', parent, name); | |
48 return new io.File(fullPath).readAsBytes() | |
49 .then((actualContents) { | |
50 if (orderedIterableEquals(contents, actualContents)) return; | |
51 if (isBinary) { | |
52 // TODO(nweiz): show a hex dump here if the data is small enough. | |
53 throw "File $nameDescription didn't contain the expected binary " | |
54 "data."; | |
55 } | |
56 var description = nameDescription; | |
57 if (name is! String) { | |
58 description = "'${path.basename(fullPath)}' (matching $description)"; | |
59 } | |
60 throw _textMismatchMessage(description, textContents, | |
61 new String.fromCharCodes(actualContents));; | |
62 }); | |
63 }, 'validating file $nameDescription'); | |
64 | |
65 Stream<List<int>> load(String pathToLoad) => errorStream("Can't load " | |
66 "'$pathToLoad' from within $nameDescription: not a directory."); | |
Bob Nystrom
2013/02/22 22:08:57
Given that Directory is the only type that will im
nweiz
2013/02/22 23:05:21
Done.
| |
67 | |
68 Stream<List<int>> read() => new Future.immediate(contents).asStream(); | |
69 | |
70 String describe() { | |
71 if (name is String) return name; | |
72 return 'file matching $nameDescription'; | |
73 } | |
74 } | |
75 | |
76 String _textMismatchMessage(String description, String expected, | |
77 String actual) { | |
78 final expectedLines = expected.split('\n'); | |
79 final actualLines = actual.split('\n'); | |
80 | |
81 var results = []; | |
82 | |
83 // Compare them line by line to see which ones match. | |
84 var length = math.max(expectedLines.length, actualLines.length); | |
85 for (var i = 0; i < length; i++) { | |
86 if (i >= actualLines.length) { | |
87 // Missing output. | |
88 results.add('? ${expectedLines[i]}'); | |
89 } else if (i >= expectedLines.length) { | |
90 // Unexpected extra output. | |
91 results.add('X ${actualLines[i]}'); | |
92 } else { | |
93 var expectedLine = expectedLines[i]; | |
94 var actualLine = actualLines[i]; | |
95 | |
96 if (expectedLine != actualLine) { | |
97 // Mismatched lines. | |
98 results.add('X $actualLine'); | |
99 } else { | |
100 // Matched lines. | |
101 results.add('| $actualLine'); | |
102 } | |
103 } | |
104 } | |
105 | |
106 return "File $description should contain:\n" | |
107 "${prefixLines(expected)}\n" | |
108 "but actually contained:\n" | |
109 "${results.join('\n')}"; | |
110 } | |
OLD | NEW |