Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2014, 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 import 'dart:io'; | |
| 6 | |
| 7 import 'package:glob/glob.dart'; | |
| 8 import 'package:glob/src/utils.dart'; | |
| 9 import 'package:path/path.dart' as p; | |
| 10 import 'package:scheduled_test/descriptor.dart' as d; | |
| 11 import 'package:scheduled_test/scheduled_test.dart'; | |
| 12 | |
| 13 String sandbox; | |
| 14 | |
| 15 void main() { | |
| 16 setUp(() { | |
| 17 scheduleSandbox(); | |
| 18 | |
| 19 d.dir("foo", [ | |
| 20 d.file("bar"), | |
| 21 d.dir("baz", [ | |
| 22 d.file("bang"), | |
| 23 d.file("qux") | |
| 24 ]) | |
| 25 ]).create(); | |
| 26 }); | |
| 27 | |
| 28 test("list() fails if the context doesn't match the system context", () { | |
| 29 expect(new Glob("*", context: p.url).list, throwsStateError); | |
| 30 }); | |
| 31 | |
| 32 test("listSync() fails if the context doesn't match the system context", () { | |
| 33 expect(new Glob("*", context: p.url).listSync, throwsStateError); | |
| 34 }); | |
| 35 | |
| 36 syncAndAsync((list) { | |
| 37 group("literals", () { | |
| 38 test("lists a single literal", () { | |
| 39 expect(list("foo/baz/qux"), completion(equals(["foo/baz/qux"]))); | |
| 40 }); | |
| 41 | |
| 42 test("lists a non-matching literal", () { | |
| 43 expect(list("foo/baz/nothing"), completion(isEmpty)); | |
| 44 }); | |
| 45 }); | |
| 46 | |
| 47 group("star", () { | |
| 48 test("lists within filenames but not across directories", () { | |
| 49 expect(list("foo/b*"), | |
| 50 completion(unorderedEquals(["foo/bar", "foo/baz"]))); | |
| 51 }); | |
| 52 | |
| 53 test("lists the empy string", () { | |
| 54 expect(list("foo/bar*"), completion(equals(["foo/bar"]))); | |
| 55 }); | |
| 56 }); | |
| 57 | |
| 58 group("double star", () { | |
| 59 test("lists within filenames", () { | |
| 60 expect(list("foo/baz/**"), | |
| 61 completion(unorderedEquals(["foo/baz/qux", "foo/baz/bang"]))); | |
| 62 }); | |
| 63 | |
| 64 test("lists the empty string", () { | |
| 65 expect(list("foo/bar**"), completion(equals(["foo/bar"]))); | |
| 66 }); | |
| 67 | |
| 68 test("lists recursively", () { | |
| 69 expect(list("foo/**"), completion(unorderedEquals( | |
|
Bob Nystrom
2014/09/18 22:17:40
How about using "foo/ba**" here to validate that "
nweiz
2014/09/22 23:48:40
Done.
| |
| 70 ["foo/bar", "foo/baz", "foo/baz/qux", "foo/baz/bang"]))); | |
| 71 }); | |
| 72 | |
| 73 test("lists recursively in the middle of a glob", () { | |
| 74 d.dir("deep", [ | |
| 75 d.dir("a", [ | |
| 76 d.dir("b", [ | |
| 77 d.dir("c", [d.file("d")]) | |
| 78 ]) | |
| 79 ]) | |
| 80 ]).create(); | |
| 81 | |
| 82 expect(list("deep/**/?/?"), | |
| 83 completion(unorderedEquals(["deep/a/b/c", "deep/a/b/c/d"]))); | |
|
Bob Nystrom
2014/09/18 22:17:40
It would be good to have a couple of non-matching
nweiz
2014/09/22 23:48:40
Done.
| |
| 84 }); | |
| 85 }); | |
| 86 | |
| 87 group("any char", () { | |
| 88 test("matches a character", () { | |
| 89 expect(list("foo/ba?"), | |
| 90 completion(unorderedEquals(["foo/bar", "foo/baz"]))); | |
| 91 }); | |
| 92 | |
| 93 test("doesn't match a separator", () { | |
| 94 expect(list("foo?bar"), completion(isEmpty)); | |
| 95 }); | |
| 96 }); | |
| 97 | |
| 98 group("range", () { | |
| 99 test("matches a range of characters", () { | |
| 100 expect(list("foo/ba[a-z]"), | |
| 101 completion(unorderedEquals(["foo/bar", "foo/baz"]))); | |
| 102 }); | |
| 103 | |
| 104 test("matches a specific list of characters", () { | |
| 105 expect(list("foo/ba[rz]"), | |
| 106 completion(unorderedEquals(["foo/bar", "foo/baz"]))); | |
| 107 }); | |
|
Bob Nystrom
2014/09/18 22:17:41
These could both benefit from a negative example.
nweiz
2014/09/22 23:48:40
Done.
| |
| 108 }); | |
| 109 | |
| 110 test("the same file shouldn't be non-recursively listed multiple times", | |
| 111 () { | |
| 112 d.dir("multi", [ | |
| 113 d.dir("start-end", [d.file("file")]) | |
| 114 ]).create(); | |
| 115 | |
| 116 expect(list("multi/{start-*/f*,*-end/*e}"), | |
| 117 completion(equals(["multi/start-end/file"]))); | |
| 118 }); | |
| 119 | |
| 120 test("the same file shouldn't be recursively listed multiple times", () { | |
| 121 d.dir("multi", [ | |
| 122 d.dir("a", [ | |
| 123 d.dir("b", [ | |
| 124 d.file("file"), | |
| 125 d.dir("c", [ | |
| 126 d.file("file") | |
| 127 ]) | |
| 128 ]), | |
| 129 d.dir("x", [ | |
| 130 d.dir("y", [ | |
| 131 d.file("file") | |
| 132 ]) | |
| 133 ]) | |
| 134 ]) | |
| 135 ]).create(); | |
| 136 | |
| 137 expect(list("multi/{*/*/*/file,a/**/file}"), completion(unorderedEquals([ | |
| 138 "multi/a/b/file", "multi/a/b/c/file", "multi/a/x/y/file" | |
| 139 ]))); | |
| 140 }); | |
| 141 | |
| 142 group("with symlinks", () { | |
| 143 setUp(() { | |
| 144 schedule(() { | |
| 145 return new Link(p.join(sandbox, "dir", "link")) | |
| 146 .create(p.join(sandbox, "foo", "baz"), recursive: true); | |
| 147 }, "symlink foo/baz to dir/link"); | |
| 148 }); | |
| 149 | |
| 150 test("follows symlinks by default", () { | |
| 151 expect(list("dir/**"), completion(unorderedEquals([ | |
| 152 "dir/link", "dir/link/bang", "dir/link/qux" | |
| 153 ]))); | |
| 154 }); | |
| 155 | |
| 156 test("doesn't follow symlinks with followLinks: false", () { | |
| 157 expect(list("dir/**", followLinks: false), | |
| 158 completion(equals(["dir/link"]))); | |
| 159 }); | |
| 160 | |
| 161 test("shouldn't crash on broken symlinks", () { | |
| 162 schedule(() { | |
| 163 return new Directory(p.join(sandbox, "foo")).delete(recursive: true); | |
| 164 }); | |
| 165 | |
| 166 expect(list("dir/**"), completion(equals(["dir/link"]))); | |
| 167 }); | |
| 168 }); | |
| 169 | |
| 170 test("always lists recursively with recursive: true", () { | |
| 171 expect(list("foo", recursive: true), completion(unorderedEquals( | |
| 172 ["foo", "foo/bar", "foo/baz", "foo/baz/qux", "foo/baz/bang"]))); | |
| 173 }); | |
| 174 | |
| 175 test("doesn't crash on non-existent directories", () { | |
| 176 expect(list("non/existent/**"), completion(isEmpty)); | |
| 177 }); | |
| 178 | |
| 179 test("lists an absolute glob", () { | |
| 180 expect(schedule(() { | |
| 181 var pattern = separatorToForwardSlash( | |
| 182 p.absolute(p.join(sandbox, 'foo/baz/**'))); | |
| 183 | |
| 184 return list(pattern); | |
| 185 }), completion(unorderedEquals(["foo/baz/bang", "foo/baz/qux"]))); | |
| 186 }); | |
| 187 }); | |
| 188 } | |
| 189 | |
| 190 typedef Future<List<String>> ListFn(String glob, | |
| 191 {bool recursive, bool followLinks}); | |
| 192 | |
| 193 /// Runs [callback] in two groups with two values of [listFn]: one that uses | |
| 194 /// [Glob.list], one that uses [Glob.listSync]. | |
| 195 void syncAndAsync(callback(ListFn listFn)) { | |
| 196 group("async", () { | |
| 197 callback((glob, {recursive: false, followLinks: true}) { | |
| 198 return schedule(() { | |
| 199 return new Glob(glob, recursive: recursive) | |
| 200 .list(root: sandbox, followLinks: followLinks) | |
| 201 .map((entity) { | |
| 202 return separatorToForwardSlash( | |
| 203 p.relative(entity.path, from: sandbox)); | |
| 204 }).toList(); | |
| 205 }, 'listing $glob'); | |
| 206 }); | |
| 207 }); | |
| 208 | |
| 209 group("sync", () { | |
| 210 callback((glob, {recursive: false, followLinks: true}) { | |
| 211 return schedule(() { | |
| 212 return new Glob(glob, recursive: recursive) | |
| 213 .listSync(root: sandbox, followLinks: followLinks) | |
| 214 .map((entity) { | |
| 215 return separatorToForwardSlash( | |
| 216 p.relative(entity.path, from: sandbox)); | |
| 217 }).toList(); | |
| 218 }, 'listing $glob'); | |
| 219 }); | |
| 220 }); | |
| 221 } | |
| 222 | |
| 223 void scheduleSandbox() { | |
| 224 schedule(() { | |
| 225 return Directory.systemTemp.createTemp('glob_').then((dir) { | |
| 226 sandbox = dir.path; | |
| 227 d.defaultRoot = sandbox; | |
| 228 }); | |
| 229 }, 'creating sandbox'); | |
| 230 | |
| 231 currentSchedule.onComplete.schedule(() { | |
| 232 d.defaultRoot = null; | |
| 233 if (sandbox == null) return null; | |
| 234 var oldSandbox = sandbox; | |
| 235 sandbox = null; | |
| 236 return new Directory(oldSandbox).delete(recursive: true); | |
| 237 }); | |
| 238 } | |
| OLD | NEW |