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