knife-essentials 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. data/LICENSE +201 -0
  2. data/README.rdoc +114 -0
  3. data/Rakefile +24 -0
  4. data/lib/chef/knife/diff.rb +28 -0
  5. data/lib/chef/knife/list.rb +107 -0
  6. data/lib/chef/knife/show.rb +30 -0
  7. data/lib/chef_fs.rb +9 -0
  8. data/lib/chef_fs/command_line.rb +91 -0
  9. data/lib/chef_fs/diff.rb +158 -0
  10. data/lib/chef_fs/file_pattern.rb +292 -0
  11. data/lib/chef_fs/file_system.rb +69 -0
  12. data/lib/chef_fs/file_system/base_fs_dir.rb +23 -0
  13. data/lib/chef_fs/file_system/base_fs_object.rb +52 -0
  14. data/lib/chef_fs/file_system/chef_server_root_dir.rb +48 -0
  15. data/lib/chef_fs/file_system/cookbook_dir.rb +80 -0
  16. data/lib/chef_fs/file_system/cookbook_file.rb +32 -0
  17. data/lib/chef_fs/file_system/cookbook_subdir.rb +25 -0
  18. data/lib/chef_fs/file_system/cookbooks_dir.rb +21 -0
  19. data/lib/chef_fs/file_system/data_bag_dir.rb +22 -0
  20. data/lib/chef_fs/file_system/data_bags_dir.rb +23 -0
  21. data/lib/chef_fs/file_system/file_system_entry.rb +36 -0
  22. data/lib/chef_fs/file_system/file_system_root_dir.rb +11 -0
  23. data/lib/chef_fs/file_system/nonexistent_fs_object.rb +23 -0
  24. data/lib/chef_fs/file_system/not_found_exception.rb +12 -0
  25. data/lib/chef_fs/file_system/rest_list_dir.rb +42 -0
  26. data/lib/chef_fs/file_system/rest_list_entry.rb +72 -0
  27. data/lib/chef_fs/knife.rb +47 -0
  28. data/lib/chef_fs/path_utils.rb +43 -0
  29. data/lib/chef_fs/version.rb +4 -0
  30. data/spec/chef_fs/diff_spec.rb +263 -0
  31. data/spec/chef_fs/file_pattern_spec.rb +507 -0
  32. data/spec/chef_fs/file_system_spec.rb +117 -0
  33. data/spec/support/file_system_support.rb +108 -0
  34. metadata +79 -0
@@ -0,0 +1,507 @@
1
+ require 'chef_fs/file_pattern'
2
+
3
+ describe ChefFS::FilePattern do
4
+ def p(str)
5
+ ChefFS::FilePattern.new(str)
6
+ end
7
+
8
+ # Different kinds of patterns
9
+ context 'with empty pattern ""' do
10
+ let(:pattern) { ChefFS::FilePattern.new('') }
11
+ it 'match?' do
12
+ pattern.match?('').should be_true
13
+ pattern.match?('/').should be_false
14
+ pattern.match?('a').should be_false
15
+ pattern.match?('a/b').should be_false
16
+ end
17
+ it 'exact_path' do
18
+ pattern.exact_path.should == ''
19
+ end
20
+ it 'could_match_children?' do
21
+ pattern.could_match_children?('').should be_false
22
+ pattern.could_match_children?('a/b').should be_false
23
+ end
24
+ end
25
+
26
+ context 'with root pattern "/"' do
27
+ let(:pattern) { ChefFS::FilePattern.new('/') }
28
+ it 'match?' do
29
+ pattern.match?('/').should be_true
30
+ pattern.match?('').should be_false
31
+ pattern.match?('a').should be_false
32
+ pattern.match?('/a').should be_false
33
+ end
34
+ it 'exact_path' do
35
+ pattern.exact_path.should == '/'
36
+ end
37
+ it 'could_match_children?' do
38
+ pattern.could_match_children?('').should be_false
39
+ pattern.could_match_children?('/').should be_false
40
+ pattern.could_match_children?('a').should be_false
41
+ pattern.could_match_children?('a/b').should be_false
42
+ pattern.could_match_children?('/a').should be_false
43
+ end
44
+ end
45
+
46
+ context 'with simple pattern "abc"' do
47
+ let(:pattern) { ChefFS::FilePattern.new('abc') }
48
+ it 'match?' do
49
+ pattern.match?('abc').should be_true
50
+ pattern.match?('a').should be_false
51
+ pattern.match?('abcd').should be_false
52
+ pattern.match?('/abc').should be_false
53
+ pattern.match?('').should be_false
54
+ pattern.match?('/').should be_false
55
+ end
56
+ it 'exact_path' do
57
+ pattern.exact_path.should == 'abc'
58
+ end
59
+ it 'could_match_children?' do
60
+ pattern.could_match_children?('').should be_false
61
+ pattern.could_match_children?('abc').should be_false
62
+ pattern.could_match_children?('/abc').should be_false
63
+ end
64
+ end
65
+
66
+ context 'with simple pattern "/abc"' do
67
+ let(:pattern) { ChefFS::FilePattern.new('/abc') }
68
+ it 'match?' do
69
+ pattern.match?('/abc').should be_true
70
+ pattern.match?('abc').should be_false
71
+ pattern.match?('a').should be_false
72
+ pattern.match?('abcd').should be_false
73
+ pattern.match?('').should be_false
74
+ pattern.match?('/').should be_false
75
+ end
76
+ it 'exact_path' do
77
+ pattern.exact_path.should == '/abc'
78
+ end
79
+ it 'could_match_children?' do
80
+ pattern.could_match_children?('abc').should be_false
81
+ pattern.could_match_children?('/abc').should be_false
82
+ pattern.could_match_children?('/').should be_true
83
+ pattern.could_match_children?('').should be_false
84
+ end
85
+ it 'exact_child_name_under' do
86
+ pattern.exact_child_name_under('/').should == 'abc'
87
+ end
88
+ end
89
+
90
+ context 'with simple pattern "abc/def/ghi"' do
91
+ let(:pattern) { ChefFS::FilePattern.new('abc/def/ghi') }
92
+ it 'match?' do
93
+ pattern.match?('abc/def/ghi').should be_true
94
+ pattern.match?('/abc/def/ghi').should be_false
95
+ pattern.match?('abc').should be_false
96
+ pattern.match?('abc/def').should be_false
97
+ end
98
+ it 'exact_path' do
99
+ pattern.exact_path.should == 'abc/def/ghi'
100
+ end
101
+ it 'could_match_children?' do
102
+ pattern.could_match_children?('abc').should be_true
103
+ pattern.could_match_children?('xyz').should be_false
104
+ pattern.could_match_children?('/abc').should be_false
105
+ pattern.could_match_children?('abc/def').should be_true
106
+ pattern.could_match_children?('abc/xyz').should be_false
107
+ pattern.could_match_children?('abc/def/ghi').should be_false
108
+ end
109
+ it 'exact_child_name_under' do
110
+ pattern.exact_child_name_under('abc').should == 'def'
111
+ pattern.exact_child_name_under('abc/def').should == 'ghi'
112
+ end
113
+ end
114
+
115
+ context 'with simple pattern "/abc/def/ghi"' do
116
+ let(:pattern) { ChefFS::FilePattern.new('/abc/def/ghi') }
117
+ it 'match?' do
118
+ pattern.match?('/abc/def/ghi').should be_true
119
+ pattern.match?('abc/def/ghi').should be_false
120
+ pattern.match?('/abc').should be_false
121
+ pattern.match?('/abc/def').should be_false
122
+ end
123
+ it 'exact_path' do
124
+ pattern.exact_path.should == '/abc/def/ghi'
125
+ end
126
+ it 'could_match_children?' do
127
+ pattern.could_match_children?('/abc').should be_true
128
+ pattern.could_match_children?('/xyz').should be_false
129
+ pattern.could_match_children?('abc').should be_false
130
+ pattern.could_match_children?('/abc/def').should be_true
131
+ pattern.could_match_children?('/abc/xyz').should be_false
132
+ pattern.could_match_children?('/abc/def/ghi').should be_false
133
+ end
134
+ it 'exact_child_name_under' do
135
+ pattern.exact_child_name_under('/').should == 'abc'
136
+ pattern.exact_child_name_under('/abc').should == 'def'
137
+ pattern.exact_child_name_under('/abc/def').should == 'ghi'
138
+ end
139
+ end
140
+
141
+ context 'with simple pattern "a\*\b"' do
142
+ let(:pattern) { ChefFS::FilePattern.new('a\*\b') }
143
+ it 'match?' do
144
+ pattern.match?('a*b').should be_true
145
+ pattern.match?('ab').should be_false
146
+ pattern.match?('acb').should be_false
147
+ pattern.match?('ab').should be_false
148
+ end
149
+ it 'exact_path' do
150
+ pattern.exact_path.should == 'a*b'
151
+ end
152
+ it 'could_match_children?' do
153
+ pattern.could_match_children?('a/*b').should be_false
154
+ end
155
+ end
156
+
157
+ context 'with star pattern "/abc/*/ghi"' do
158
+ let(:pattern) { ChefFS::FilePattern.new('/abc/*/ghi') }
159
+ it 'match?' do
160
+ pattern.match?('/abc/def/ghi').should be_true
161
+ pattern.match?('/abc/ghi').should be_false
162
+ end
163
+ it 'exact_path' do
164
+ pattern.exact_path.should be_nil
165
+ end
166
+ it 'could_match_children?' do
167
+ pattern.could_match_children?('/abc').should be_true
168
+ pattern.could_match_children?('/xyz').should be_false
169
+ pattern.could_match_children?('abc').should be_false
170
+ pattern.could_match_children?('/abc/def').should be_true
171
+ pattern.could_match_children?('/abc/xyz').should be_true
172
+ pattern.could_match_children?('/abc/def/ghi').should be_false
173
+ end
174
+ it 'exact_child_name_under' do
175
+ pattern.exact_child_name_under('/').should == 'abc'
176
+ pattern.exact_child_name_under('/abc').should == nil
177
+ pattern.exact_child_name_under('/abc/def').should == 'ghi'
178
+ end
179
+ end
180
+
181
+ context 'with star pattern "/abc/d*f/ghi"' do
182
+ let(:pattern) { ChefFS::FilePattern.new('/abc/d*f/ghi') }
183
+ it 'match?' do
184
+ pattern.match?('/abc/def/ghi').should be_true
185
+ pattern.match?('/abc/dxf/ghi').should be_true
186
+ pattern.match?('/abc/df/ghi').should be_true
187
+ pattern.match?('/abc/dxyzf/ghi').should be_true
188
+ pattern.match?('/abc/d/ghi').should be_false
189
+ pattern.match?('/abc/f/ghi').should be_false
190
+ pattern.match?('/abc/ghi').should be_false
191
+ pattern.match?('/abc/xyz/ghi').should be_false
192
+ end
193
+ it 'exact_path' do
194
+ pattern.exact_path.should be_nil
195
+ end
196
+ it 'could_match_children?' do
197
+ pattern.could_match_children?('/abc').should be_true
198
+ pattern.could_match_children?('/xyz').should be_false
199
+ pattern.could_match_children?('abc').should be_false
200
+ pattern.could_match_children?('/abc/def').should be_true
201
+ pattern.could_match_children?('/abc/xyz').should be_false
202
+ pattern.could_match_children?('/abc/dxyzf').should be_true
203
+ pattern.could_match_children?('/abc/df').should be_true
204
+ pattern.could_match_children?('/abc/d').should be_false
205
+ pattern.could_match_children?('/abc/f').should be_false
206
+ pattern.could_match_children?('/abc/def/ghi').should be_false
207
+ end
208
+ it 'exact_child_name_under' do
209
+ pattern.exact_child_name_under('/').should == 'abc'
210
+ pattern.exact_child_name_under('/abc').should == nil
211
+ pattern.exact_child_name_under('/abc/def').should == 'ghi'
212
+ end
213
+ end
214
+
215
+ context 'with star pattern "/abc/d??f/ghi"' do
216
+ let(:pattern) { ChefFS::FilePattern.new('/abc/d??f/ghi') }
217
+ it 'match?' do
218
+ pattern.match?('/abc/deef/ghi').should be_true
219
+ pattern.match?('/abc/deeef/ghi').should be_false
220
+ pattern.match?('/abc/def/ghi').should be_false
221
+ pattern.match?('/abc/df/ghi').should be_false
222
+ pattern.match?('/abc/d/ghi').should be_false
223
+ pattern.match?('/abc/f/ghi').should be_false
224
+ pattern.match?('/abc/ghi').should be_false
225
+ end
226
+ it 'exact_path' do
227
+ pattern.exact_path.should be_nil
228
+ end
229
+ it 'could_match_children?' do
230
+ pattern.could_match_children?('/abc').should be_true
231
+ pattern.could_match_children?('/xyz').should be_false
232
+ pattern.could_match_children?('abc').should be_false
233
+ pattern.could_match_children?('/abc/deef').should be_true
234
+ pattern.could_match_children?('/abc/deeef').should be_false
235
+ pattern.could_match_children?('/abc/def').should be_false
236
+ pattern.could_match_children?('/abc/df').should be_false
237
+ pattern.could_match_children?('/abc/d').should be_false
238
+ pattern.could_match_children?('/abc/f').should be_false
239
+ pattern.could_match_children?('/abc/deef/ghi').should be_false
240
+ end
241
+ it 'exact_child_name_under' do
242
+ pattern.exact_child_name_under('/').should == 'abc'
243
+ pattern.exact_child_name_under('/abc').should == nil
244
+ pattern.exact_child_name_under('/abc/deef').should == 'ghi'
245
+ end
246
+ end
247
+
248
+ context 'with star pattern "/abc/d[a-z][0-9]f/ghi"' do
249
+ let(:pattern) { ChefFS::FilePattern.new('/abc/d[a-z][0-9]f/ghi') }
250
+ it 'match?' do
251
+ pattern.match?('/abc/de1f/ghi').should be_true
252
+ pattern.match?('/abc/deef/ghi').should be_false
253
+ pattern.match?('/abc/d11f/ghi').should be_false
254
+ pattern.match?('/abc/de11f/ghi').should be_false
255
+ pattern.match?('/abc/dee1f/ghi').should be_false
256
+ pattern.match?('/abc/df/ghi').should be_false
257
+ pattern.match?('/abc/d/ghi').should be_false
258
+ pattern.match?('/abc/f/ghi').should be_false
259
+ pattern.match?('/abc/ghi').should be_false
260
+ end
261
+ it 'exact_path' do
262
+ pattern.exact_path.should be_nil
263
+ end
264
+ it 'could_match_children?' do
265
+ pattern.could_match_children?('/abc').should be_true
266
+ pattern.could_match_children?('/xyz').should be_false
267
+ pattern.could_match_children?('abc').should be_false
268
+ pattern.could_match_children?('/abc/de1f').should be_true
269
+ pattern.could_match_children?('/abc/deef').should be_false
270
+ pattern.could_match_children?('/abc/d11f').should be_false
271
+ pattern.could_match_children?('/abc/de11f').should be_false
272
+ pattern.could_match_children?('/abc/dee1f').should be_false
273
+ pattern.could_match_children?('/abc/def').should be_false
274
+ pattern.could_match_children?('/abc/df').should be_false
275
+ pattern.could_match_children?('/abc/d').should be_false
276
+ pattern.could_match_children?('/abc/f').should be_false
277
+ pattern.could_match_children?('/abc/de1f/ghi').should be_false
278
+ end
279
+ it 'exact_child_name_under' do
280
+ pattern.exact_child_name_under('/').should == 'abc'
281
+ pattern.exact_child_name_under('/abc').should == nil
282
+ pattern.exact_child_name_under('/abc/de1f').should == 'ghi'
283
+ end
284
+ end
285
+
286
+ context 'with star pattern "/abc/**/ghi"' do
287
+ let(:pattern) { ChefFS::FilePattern.new('/abc/**/ghi') }
288
+ it 'match?' do
289
+ pattern.match?('/abc/def/ghi').should be_true
290
+ pattern.match?('/abc/d/e/f/ghi').should be_true
291
+ pattern.match?('/abc/ghi').should be_false
292
+ pattern.match?('/abcdef/d/ghi').should be_false
293
+ pattern.match?('/abc/d/defghi').should be_false
294
+ pattern.match?('/xyz').should be_false
295
+ end
296
+ it 'exact_path' do
297
+ pattern.exact_path.should be_nil
298
+ end
299
+ it 'could_match_children?' do
300
+ pattern.could_match_children?('/abc').should be_true
301
+ pattern.could_match_children?('/abc/d').should be_true
302
+ pattern.could_match_children?('/abc/d/e').should be_true
303
+ pattern.could_match_children?('/abc/d/e/f').should be_true
304
+ pattern.could_match_children?('/abc/def/ghi').should be_true
305
+ pattern.could_match_children?('abc').should be_false
306
+ pattern.could_match_children?('/xyz').should be_false
307
+ end
308
+ it 'exact_child_name_under' do
309
+ pattern.exact_child_name_under('/').should == 'abc'
310
+ pattern.exact_child_name_under('/abc').should == nil
311
+ pattern.exact_child_name_under('/abc/def').should == nil
312
+ end
313
+ end
314
+
315
+ context 'with star pattern "/abc**/ghi"' do
316
+ let(:pattern) { ChefFS::FilePattern.new('/abc**/ghi') }
317
+ it 'match?' do
318
+ pattern.match?('/abc/def/ghi').should be_true
319
+ pattern.match?('/abc/d/e/f/ghi').should be_true
320
+ pattern.match?('/abc/ghi').should be_true
321
+ pattern.match?('/abcdef/ghi').should be_true
322
+ pattern.match?('/abc/defghi').should be_false
323
+ pattern.match?('/xyz').should be_false
324
+ end
325
+ it 'exact_path' do
326
+ pattern.exact_path.should be_nil
327
+ end
328
+ it 'could_match_children?' do
329
+ pattern.could_match_children?('/abc').should be_true
330
+ pattern.could_match_children?('/abcdef').should be_true
331
+ pattern.could_match_children?('/abc/d/e').should be_true
332
+ pattern.could_match_children?('/abc/d/e/f').should be_true
333
+ pattern.could_match_children?('/abc/def/ghi').should be_true
334
+ pattern.could_match_children?('abc').should be_false
335
+ end
336
+ it 'could_match_children? /abc** returns false for /xyz' do
337
+ pending 'Make could_match_children? more rigorous' do
338
+ # At the moment, we return false for this, but in the end it would be nice to return true:
339
+ pattern.could_match_children?('/xyz').should be_false
340
+ end
341
+ end
342
+ it 'exact_child_name_under' do
343
+ pattern.exact_child_name_under('/').should == nil
344
+ pattern.exact_child_name_under('/abc').should == nil
345
+ pattern.exact_child_name_under('/abc/def').should == nil
346
+ end
347
+ end
348
+
349
+ context 'with star pattern "/abc/**ghi"' do
350
+ let(:pattern) { ChefFS::FilePattern.new('/abc/**ghi') }
351
+ it 'match?' do
352
+ pattern.match?('/abc/def/ghi').should be_true
353
+ pattern.match?('/abc/def/ghi/ghi').should be_true
354
+ pattern.match?('/abc/def/ghi/jkl').should be_false
355
+ pattern.match?('/abc/d/e/f/ghi').should be_true
356
+ pattern.match?('/abc/ghi').should be_true
357
+ pattern.match?('/abcdef/ghi').should be_false
358
+ pattern.match?('/abc/defghi').should be_true
359
+ pattern.match?('/xyz').should be_false
360
+ end
361
+ it 'exact_path' do
362
+ pattern.exact_path.should be_nil
363
+ end
364
+ it 'could_match_children?' do
365
+ pattern.could_match_children?('/abc').should be_true
366
+ pattern.could_match_children?('/abcdef').should be_false
367
+ pattern.could_match_children?('/abc/d/e').should be_true
368
+ pattern.could_match_children?('/abc/d/e/f').should be_true
369
+ pattern.could_match_children?('/abc/def/ghi').should be_true
370
+ pattern.could_match_children?('abc').should be_false
371
+ pattern.could_match_children?('/xyz').should be_false
372
+ end
373
+ it 'exact_child_name_under' do
374
+ pattern.exact_child_name_under('/').should == 'abc'
375
+ pattern.exact_child_name_under('/abc').should == nil
376
+ pattern.exact_child_name_under('/abc/def').should == nil
377
+ end
378
+ end
379
+
380
+ context 'with star pattern "a**b**c"' do
381
+ let(:pattern) { ChefFS::FilePattern.new('a**b**c') }
382
+ it 'match?' do
383
+ pattern.match?('axybzwc').should be_true
384
+ pattern.match?('abc').should be_true
385
+ pattern.match?('axyzwc').should be_false
386
+ pattern.match?('ac').should be_false
387
+ pattern.match?('a/x/y/b/z/w/c').should be_true
388
+ end
389
+ it 'exact_path' do
390
+ pattern.exact_path.should be_nil
391
+ end
392
+ end
393
+
394
+ context 'normalization tests' do
395
+ it 'handles trailing slashes' do
396
+ p('abc/').normalized_pattern.should == 'abc'
397
+ p('abc/').exact_path.should == 'abc'
398
+ p('abc/').match?('abc').should be_true
399
+ p('//').normalized_pattern.should == '/'
400
+ p('//').exact_path.should == '/'
401
+ p('//').match?('/').should be_true
402
+ p('/./').normalized_pattern.should == '/'
403
+ p('/./').exact_path.should == '/'
404
+ p('/./').match?('/').should be_true
405
+ end
406
+ it 'handles multiple slashes' do
407
+ p('abc//def').normalized_pattern.should == 'abc/def'
408
+ p('abc//def').exact_path.should == 'abc/def'
409
+ p('abc//def').match?('abc/def').should be_true
410
+ p('abc//').normalized_pattern.should == 'abc'
411
+ p('abc//').exact_path.should == 'abc'
412
+ p('abc//').match?('abc').should be_true
413
+ end
414
+ it 'handles dot' do
415
+ p('abc/./def').normalized_pattern.should == 'abc/def'
416
+ p('abc/./def').exact_path.should == 'abc/def'
417
+ p('abc/./def').match?('abc/def').should be_true
418
+ p('./abc/def').normalized_pattern.should == 'abc/def'
419
+ p('./abc/def').exact_path.should == 'abc/def'
420
+ p('./abc/def').match?('abc/def').should be_true
421
+ p('/.').normalized_pattern.should == '/'
422
+ p('/.').exact_path.should == '/'
423
+ p('/.').match?('/').should be_true
424
+ end
425
+ it 'handles dot by itself', :pending => "decide what to do with dot by itself" do
426
+ p('.').normalized_pattern.should == '.'
427
+ p('.').exact_path.should == '.'
428
+ p('.').match?('.').should be_true
429
+ p('./').normalized_pattern.should == '.'
430
+ p('./').exact_path.should == '.'
431
+ p('./').match?('.').should be_true
432
+ end
433
+ it 'handles dotdot' do
434
+ p('abc/../def').normalized_pattern.should == 'def'
435
+ p('abc/../def').exact_path.should == 'def'
436
+ p('abc/../def').match?('def').should be_true
437
+ p('abc/def/../..').normalized_pattern.should == ''
438
+ p('abc/def/../..').exact_path.should == ''
439
+ p('abc/def/../..').match?('').should be_true
440
+ p('/*/../def').normalized_pattern.should == '/def'
441
+ p('/*/../def').exact_path.should == '/def'
442
+ p('/*/../def').match?('/def').should be_true
443
+ p('/*/*/../def').normalized_pattern.should == '/*/def'
444
+ p('/*/*/../def').exact_path.should be_nil
445
+ p('/*/*/../def').match?('/abc/def').should be_true
446
+ p('/abc/def/../..').normalized_pattern.should == '/'
447
+ p('/abc/def/../..').exact_path.should == '/'
448
+ p('/abc/def/../..').match?('/').should be_true
449
+ p('abc/../../def').normalized_pattern.should == '../def'
450
+ p('abc/../../def').exact_path.should == '../def'
451
+ p('abc/../../def').match?('../def').should be_true
452
+ end
453
+ it 'handles dotdot with double star' do
454
+ p('abc**/def/../ghi').exact_path.should be_nil
455
+ p('abc**/def/../ghi').match?('abc/ghi').should be_true
456
+ p('abc**/def/../ghi').match?('abc/x/y/z/ghi').should be_true
457
+ p('abc**/def/../ghi').match?('ghi').should be_false
458
+ end
459
+ it 'raises error on dotdot with overlapping double star' do
460
+ lambda { ChefFS::FilePattern.new('abc/**/../def').exact_path }.should raise_error(ArgumentError)
461
+ lambda { ChefFS::FilePattern.new('abc/**/abc/../../def').exact_path }.should raise_error(ArgumentError)
462
+ end
463
+ it 'handles leading dotdot' do
464
+ p('../abc/def').exact_path.should == '../abc/def'
465
+ p('../abc/def').match?('../abc/def').should be_true
466
+ p('/../abc/def').exact_path.should == '/abc/def'
467
+ p('/../abc/def').match?('/abc/def').should be_true
468
+ p('..').exact_path.should == '..'
469
+ p('..').match?('..').should be_true
470
+ p('/..').exact_path.should == '/'
471
+ p('/..').match?('/').should be_true
472
+ end
473
+ end
474
+
475
+
476
+ # match?
477
+ # - single element matches (empty, fixed, ?, *, characters, escapes)
478
+ # - nested matches
479
+ # - absolute matches
480
+ # - trailing slashes
481
+ # - **
482
+
483
+ # exact_path
484
+ # - empty
485
+ # - single element and nested matches, with escapes
486
+ # - absolute and relative
487
+ # - ?, *, characters, **
488
+
489
+ # could_match_children?
490
+ #
491
+ #
492
+ #
493
+ #
494
+ context 'with pattern "abc"' do
495
+ end
496
+
497
+ context 'with pattern "/abc"' do
498
+ end
499
+
500
+ context 'with pattern "abc/def/ghi"' do
501
+ end
502
+
503
+ context 'with pattern "/abc/def/ghi"' do
504
+ end
505
+
506
+ # Exercise the different methods to their maximum
507
+ end