diff options
author | Steven Knight <knight@baldmt.com> | 2007-12-13 04:25:43 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2007-12-13 04:25:43 (GMT) |
commit | 8dfbc4aafc99cd41c9e89b245e0772c862e073a6 (patch) | |
tree | 86299c32c336859f1bf05c6e3800d8c54282ccd8 /src/engine/SCons/Node/FSTests.py | |
parent | 70591272485606edf2293e7d9fa33113ac9cb00c (diff) | |
download | SCons-8dfbc4aafc99cd41c9e89b245e0772c862e073a6.zip SCons-8dfbc4aafc99cd41c9e89b245e0772c862e073a6.tar.gz SCons-8dfbc4aafc99cd41c9e89b245e0772c862e073a6.tar.bz2 |
Merged revisions 2454-2525 via svnmerge from
http://scons.tigris.org/svn/scons/branches/core
........
r2455 | stevenknight | 2007-09-20 01:27:23 -0500 (Thu, 20 Sep 2007) | 2 lines
Use ${TARGET.base} to make sure $TARGET attributes stay fixed.
........
r2456 | stevenknight | 2007-09-25 11:52:30 -0500 (Tue, 25 Sep 2007) | 5 lines
Issue 1734: Avoid having content signature calculation of Alias Nodes
consume excessive amounts of memory by having an Alias' "contents" be a
concatenation of the children's signatures, not the children's contents.
(Ken Deeter)
........
r2457 | stevenknight | 2007-09-26 12:18:49 -0500 (Wed, 26 Sep 2007) | 2 lines
Add an Options.UnknownOptions() method.
........
r2458 | stevenknight | 2007-09-26 16:26:05 -0500 (Wed, 26 Sep 2007) | 2 lines
Add a compatibility fnmatch.filter() function.
........
r2459 | stevenknight | 2007-09-27 18:26:03 -0500 (Thu, 27 Sep 2007) | 3 lines
Add a new Glob() function that matches in-memory Nodes as well as on-disk
files (including matching repository and source directories).
........
r2460 | stevenknight | 2007-09-28 15:01:37 -0500 (Fri, 28 Sep 2007) | 5 lines
Issue 1020: fix use of Clean() for files created by "side effect"
in BuildDir() by removing the file by absolute path, not by what str()
returns. (It will think that the file is a source file and return a
path to the source directory.)
........
r2461 | stevenknight | 2007-09-29 05:39:09 -0500 (Sat, 29 Sep 2007) | 2 lines
Update to TestCmd 0.28 modules.
........
r2462 | stevenknight | 2007-09-29 05:49:29 -0500 (Sat, 29 Sep 2007) | 3 lines
The RPM packaging can no longer take a "target" argument and produces
an appropriate error message. Update the test accordingly.
........
r2463 | pscholl | 2007-09-30 08:57:01 -0500 (Sun, 30 Sep 2007) | 3 lines
fix documentation issues (issue 1736 on the bugtracker)
........
r2464 | pscholl | 2007-09-30 09:39:49 -0500 (Sun, 30 Sep 2007) | 3 lines
fix target set up if multiple package builders are specified at once.
........
r2465 | stevenknight | 2007-10-01 13:00:44 -0500 (Mon, 01 Oct 2007) | 3 lines
Update to TestCmd 0.29, with new methods for searching for a list
of lines in output.
........
r2466 | stevenknight | 2007-10-01 13:58:41 -0500 (Mon, 01 Oct 2007) | 4 lines
Issue 1737: Fix use of Configure() contexts with the -c (clean) and -h
(help) options by supporting the ability to *configure* whether or no
configure context tests are executed during those modes.
........
r2467 | stevenknight | 2007-10-01 16:58:21 -0500 (Mon, 01 Oct 2007) | 2 lines
Update to TestCmd 0.30, with a new TestCmd.rmdir() method.
........
r2468 | stevenknight | 2007-10-01 17:05:44 -0500 (Mon, 01 Oct 2007) | 4 lines
Issue 1586: Capture a test script for "ghost" entries in .sconsign files.
Test cases by Morten Elo Peterson and Jason Orendorff, packaged by
Gary Oberbrunner.
........
r2469 | stevenknight | 2007-10-04 11:21:12 -0500 (Thu, 04 Oct 2007) | 4 lines
When cloning a construction environment, have the clone record the
re-binding of the methods that were added to the original construction
environment, so that further clones have their methods re-bound as well.
........
r2470 | stevenknight | 2007-10-05 13:02:34 -0500 (Fri, 05 Oct 2007) | 3 lines
Refactor the Glob() code for efficiency and readability. (Greg Noel)
Refactor Glob() unit tests for platform-independence.
........
r2471 | stevenknight | 2007-10-09 10:49:15 -0500 (Tue, 09 Oct 2007) | 2 lines
Back out Glob() refactoring to avoid Repository breakage.
........
r2472 | stevenknight | 2007-10-09 12:16:33 -0500 (Tue, 09 Oct 2007) | 3 lines
Fix ToolInitializer-related infinite recursion when the BUILDERS dict
and the environment attributes can get out of sync.
........
r2473 | stevenknight | 2007-10-10 14:39:19 -0500 (Wed, 10 Oct 2007) | 4 lines
Fix a race condition in the -j sub-test by using marker directories to
make sure (?) that the two build scripts are actually executed in parallel
(regardless of system load).
........
r2474 | stevenknight | 2007-10-11 12:32:07 -0500 (Thu, 11 Oct 2007) | 4 lines
Re-fix globbing on case-insensitive systems like Windows. Slight
efficiency improvements as well (avoiding unnecessary calls to
fnmatch.filter()).
........
r2475 | stevenknight | 2007-10-11 15:04:42 -0500 (Thu, 11 Oct 2007) | 3 lines
Refactor the Node lookup logic to fix handling Windows drive letters
after an initial '#'.
........
r2476 | stevenknight | 2007-10-12 00:01:31 -0500 (Fri, 12 Oct 2007) | 2 lines
Fix nested scope issues (for the benefit of older Python versions).
........
r2477 | stevenknight | 2007-10-12 11:36:21 -0500 (Fri, 12 Oct 2007) | 2 lines
Issue 1743: Document '#' interpretation, with examples.
........
r2478 | stevenknight | 2007-10-12 12:17:50 -0500 (Fri, 12 Oct 2007) | 3 lines
Fix the ability of our default ActionFactory function to handle Nodes
as input.
........
r2479 | stevenknight | 2007-10-12 13:53:37 -0500 (Fri, 12 Oct 2007) | 4 lines
Enhance Options() file execution to add the file's directory to sys.path
(and remove it afterwards) and to add a __name__ variable that can be
used for introspecting on the file's location.
........
r2480 | stevenknight | 2007-10-14 17:57:09 -0500 (Sun, 14 Oct 2007) | 4 lines
Remove unnecessary os.path.normpath() calls when looking up directories
or files by checking for whether we can just tack on a single entry name
to the already-normalized lookup path of the directory Node.
........
r2481 | stevenknight | 2007-10-17 01:08:47 -0500 (Wed, 17 Oct 2007) | 2 lines
Add a GetBuildFailures() function.
........
r2482 | stevenknight | 2007-10-17 09:56:18 -0500 (Wed, 17 Oct 2007) | 2 lines
Fix the GetBuildFailures() example in the man page.
........
r2483 | stevenknight | 2007-10-17 10:54:21 -0500 (Wed, 17 Oct 2007) | 3 lines
Use sys.exitfunc if there's no atexit module (Python 1.5.2).
Sort the failure list for deterministic build output under system load.
........
r2484 | stevenknight | 2007-10-20 12:33:07 -0500 (Sat, 20 Oct 2007) | 2 lines
Use more efficient Decider() defaults instead of {Target,Source}Signatures().
........
r2485 | stevenknight | 2007-10-20 17:42:27 -0500 (Sat, 20 Oct 2007) | 2 lines
Windows portability in GetBuildFailures() test scripts.
........
r2486 | stevenknight | 2007-10-20 20:46:26 -0500 (Sat, 20 Oct 2007) | 2 lines
Windows portability: rename internal copy.py script, use a stub instead of tar.
........
r2487 | stevenknight | 2007-10-24 23:36:24 -0500 (Wed, 24 Oct 2007) | 4 lines
Whenever a script configures SConsignFile(None), make sure it uses
stub compiler and linker scripts, not the system ones, to avoid writing
(or trying to write) .sconsign files in system directories.
........
r2488 | stevenknight | 2007-10-26 13:57:38 -0500 (Fri, 26 Oct 2007) | 2 lines
Issue 1764: Fix test-script portability issues on Solaris.
........
r2489 | stevenknight | 2007-10-27 07:37:37 -0500 (Sat, 27 Oct 2007) | 3 lines
Issue 1757: add a CheckTypeSize() call to Configure contexts
(David Cournapeau).
........
r2490 | stevenknight | 2007-10-28 07:58:30 -0500 (Sun, 28 Oct 2007) | 2 lines
Python 1.5.2 compatibility: no use of +=.
........
r2491 | stevenknight | 2007-10-29 12:13:35 -0500 (Mon, 29 Oct 2007) | 3 lines
Issue 1758: Fix the SCons packaging build for use with shared-lib
versions of Python and to avoid .egg-info naming issues.
........
r2492 | stevenknight | 2007-10-29 14:09:57 -0500 (Mon, 29 Oct 2007) | 2 lines
Document the "expect" argument to CheckTypeSize(). (David Cournapeau)
........
r2493 | stevenknight | 2007-11-05 20:57:27 -0600 (Mon, 05 Nov 2007) | 2 lines
Fix use of Glob() when a pattern is below an explicitly-named subdirectory.
........
r2495 | stevenknight | 2007-11-12 22:58:12 -0600 (Mon, 12 Nov 2007) | 5 lines
Add a get_sources() access method to avoid an O(n^2) problem when adding
sources to an Executor object. The old code weeded out duplicates
whenever a new source was added; the new code only does that when the
source is list going to be used.
........
r2496 | stevenknight | 2007-11-15 12:19:55 -0600 (Thu, 15 Nov 2007) | 4 lines
Redefine the $WINDOWSPROGMANIFESTSUFFIX and
$WINDOWSSHLIBMANIFESTSUFFIX variables so they pick up changes to
the underlying $SHLIBSUFFIX and $PROGSUFFIX variables.
........
r2497 | stevenknight | 2007-11-18 17:11:52 -0600 (Sun, 18 Nov 2007) | 4 lines
Support .status and .command attributes of BuildError exceptions.
Change Action objects to return BuildError objects (not raise them)
when an action fails.
........
r2498 | stevenknight | 2007-11-19 07:27:16 -0600 (Mon, 19 Nov 2007) | 3 lines
When converting .sconsign paths to Nodes, use the more efficient
_lookup_abs() method.
........
r2499 | stevenknight | 2007-11-25 00:18:20 -0600 (Sun, 25 Nov 2007) | 3 lines
Move the reflection-checking is_under() logic from the .srcdir_list()
method to the .srcdir_duplicate() method.
........
r2500 | stevenknight | 2007-11-25 00:31:33 -0600 (Sun, 25 Nov 2007) | 2 lines
Have the .srcnode() method use the .srcdir_list() method.
........
r2501 | stevenknight | 2007-11-28 22:56:39 -0600 (Wed, 28 Nov 2007) | 3 lines
Issue 1845: Have single-source Builders (like Object()) return
NodeList objects even when called with multiple files.
........
r2502 | stevenknight | 2007-11-28 23:00:46 -0600 (Wed, 28 Nov 2007) | 2 lines
Issue 1845: Document the NodeList behavior w.r.t Python's += operator.
........
r2503 | stevenknight | 2007-11-29 09:35:31 -0600 (Thu, 29 Nov 2007) | 3 lines
Issue 1840: Fix a lot of typos in the man page and Users' Guide.
(Malte Helmert)
........
r2504 | stevenknight | 2007-11-29 10:41:44 -0600 (Thu, 29 Nov 2007) | 3 lines
Issue 1841: Fix --implicit-cache spurious rebuilds and inefficiency
when using Builders that produce multiple targets. (Benoit Belley)
........
r2505 | stevenknight | 2007-11-30 17:36:03 -0600 (Fri, 30 Nov 2007) | 3 lines
Unit test fix for Python 1.5.2, which can't .extend() lists with
UserList objects.
........
r2506 | stevenknight | 2007-11-30 20:37:14 -0600 (Fri, 30 Nov 2007) | 2 lines
Python 1.5.2 portability: use string.join(), not ' '.join().
........
r2507 | stevenknight | 2007-11-30 21:42:19 -0600 (Fri, 30 Nov 2007) | 3 lines
When searching directory lists like $CPPPATH, don't make Dir Nodes for
directories that don't exist on disk.
........
r2508 | stevenknight | 2007-12-01 00:14:35 -0600 (Sat, 01 Dec 2007) | 2 lines
Add a Requires() function for specifying order-only prerequisites.
........
r2509 | stevenknight | 2007-12-01 07:32:24 -0600 (Sat, 01 Dec 2007) | 3 lines
Handle absolute paths without infinite recursion in the new code that
searches for implicit dependencies without creating unnecessary Dir Nodes.
........
r2510 | stevenknight | 2007-12-03 15:11:56 -0600 (Mon, 03 Dec 2007) | 2 lines
Restore the rel_path() method, for the benefit of SConscript files using it.
........
r2511 | stevenknight | 2007-12-04 00:34:02 -0600 (Tue, 04 Dec 2007) | 4 lines
User's Guide updates for the Big Signature refactoring, capturing mention
of things that still need documenting, and other changes from re-running
the examples through the latest code.
........
r2512 | stevenknight | 2007-12-04 08:48:51 -0600 (Tue, 04 Dec 2007) | 3 lines
Issue 1846: allow building only part of the dependency graph when
BuildDir(duplicate=0) is used. (Benoit Belley)
........
r2513 | stevenknight | 2007-12-06 05:02:56 -0600 (Thu, 06 Dec 2007) | 3 lines
Have the code that avoids creating unnecessary Dir Nodes when searching
$*PATH variables handle absolute paths with Windows drive letters.
........
r2514 | stevenknight | 2007-12-08 07:44:15 -0600 (Sat, 08 Dec 2007) | 6 lines
Issue 1852: Make the default behavior of
{Source,Target}Signatures('timestamp') equivalent to
'timestamp-match', not 'timestamp-newer'. Fix use of CacheDir with
Decider('timestamp-newer') by updating the modification time when copying
files from the cache.
........
r2515 | stevenknight | 2007-12-08 08:23:02 -0600 (Sat, 08 Dec 2007) | 4 lines
Update the mock compiler inin/sconsoutput to use $CPPPATH.
Capture the ripple effect in the Troubleshooting appendix.
Also add a -t option to the mock "touch" command.
........
r2516 | stevenknight | 2007-12-08 09:16:11 -0600 (Sat, 08 Dec 2007) | 3 lines
Update the Dependencies chapter for use of the Decider() function,
and to now discourage use of SourceSignatures() and TargetSignatures().
........
r2517 | stevenknight | 2007-12-08 12:31:10 -0600 (Sat, 08 Dec 2007) | 4 lines
Issue 1721: On Windows, wrap __builtin__.close() and __builtin__.file()
to disable file handle inheritance on any files opened by SCons during
the run.
........
r2518 | stevenknight | 2007-12-11 17:33:20 -0600 (Tue, 11 Dec 2007) | 4 lines
Prevent the _get_str() method from causing underlying stat() values
to be cached if we're not yet saving the string representations of
FS.Base() Nodes.
........
r2519 | stevenknight | 2007-12-11 23:27:05 -0600 (Tue, 11 Dec 2007) | 4 lines
Add a warning about the unreliability of -j if the pywin32 modules aren't
available or are old and can't suppress file handle inheritance.
Add a release note about the change to open() and file().
........
r2520 | stevenknight | 2007-12-11 23:28:05 -0600 (Tue, 11 Dec 2007) | 2 lines
Add an overlooked update, fix spelling.
........
r2521 | stevenknight | 2007-12-12 09:12:42 -0600 (Wed, 12 Dec 2007) | 3 lines
Use &TargetSignatures; (replace missing ampersand) in the title of
that section. Move the &Depends; section to before the &Ignore; section.
........
r2522 | stevenknight | 2007-12-12 09:20:46 -0600 (Wed, 12 Dec 2007) | 3 lines
Final documentation update for checkpoint release: propagate .in changes
to .xml files.
........
r2523 | stevenknight | 2007-12-12 09:29:11 -0600 (Wed, 12 Dec 2007) | 2 lines
Update release lines for new checkpoint release.
........
Diffstat (limited to 'src/engine/SCons/Node/FSTests.py')
-rw-r--r-- | src/engine/SCons/Node/FSTests.py | 486 |
1 files changed, 440 insertions, 46 deletions
diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index 225226d..b698e87 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -288,8 +288,9 @@ class BuildDirTestCase(unittest.TestCase): assert not f7.exists() assert f7.rexists() - assert f7.rfile().path == os.path.normpath(test.workpath('rep1/build/var1/test2.out')),\ - f7.rfile().path + r = f7.rfile().path + expect = os.path.normpath(test.workpath('rep1/build/var1/test2.out')) + assert r == expect, (repr(r), repr(expect)) assert not f8.exists() assert f8.rexists() @@ -534,6 +535,8 @@ class BuildDirTestCase(unittest.TestCase): 'work/src/b1/b2', 'work/src/b1/b2/b1', 'work/src/b1/b2/b1/b2', + 'work/src/b1/b2/b1/b2/b1', + 'work/src/b1/b2/b1/b2/b1/b2', ] srcnode_map = { @@ -543,6 +546,10 @@ class BuildDirTestCase(unittest.TestCase): 'work/src/b1/b2/b1/f' : 'work/src/b1/f', 'work/src/b1/b2/b1/b2' : 'work/src/b1/b2', 'work/src/b1/b2/b1/b2/f' : 'work/src/b1/b2/f', + 'work/src/b1/b2/b1/b2/b1' : 'work/src/b1/b2/b1', + 'work/src/b1/b2/b1/b2/b1/f' : 'work/src/b1/b2/b1/f', + 'work/src/b1/b2/b1/b2/b1/b2' : 'work/src/b1/b2/b1/b2', + 'work/src/b1/b2/b1/b2/b1/b2/f' : 'work/src/b1/b2/b1/b2/f', } alter_map = { @@ -910,43 +917,47 @@ class FSTestCase(_tempdirTestCase): drive, path = os.path.splitdrive(os.getcwd()) + def _do_Dir_test(lpath, path_, abspath_, up_path_, sep, fileSys=fs, drive=drive): + dir = fileSys.Dir(string.replace(lpath, '/', sep)) + + if os.sep != '/': + path_ = string.replace(path_, '/', os.sep) + abspath_ = string.replace(abspath_, '/', os.sep) + up_path_ = string.replace(up_path_, '/', os.sep) + + def strip_slash(p, drive=drive): + if p[-1] == os.sep and len(p) > 1: + p = p[:-1] + if p[0] == os.sep: + p = drive + p + return p + path = strip_slash(path_) + abspath = strip_slash(abspath_) + up_path = strip_slash(up_path_) + name = string.split(abspath, os.sep)[-1] + + assert dir.name == name, \ + "dir.name %s != expected name %s" % \ + (dir.name, name) + assert dir.path == path, \ + "dir.path %s != expected path %s" % \ + (dir.path, path) + assert str(dir) == path, \ + "str(dir) %s != expected path %s" % \ + (str(dir), path) + assert dir.get_abspath() == abspath, \ + "dir.abspath %s != expected absolute path %s" % \ + (dir.get_abspath(), abspath) + assert dir.up().path == up_path, \ + "dir.up().path %s != expected parent path %s" % \ + (dir.up().path, up_path) + for sep in seps: - def Dir_test(lpath, path_, abspath_, up_path_, fileSys=fs, s=sep, drive=drive): - dir = fileSys.Dir(string.replace(lpath, '/', s)) - - if os.sep != '/': - path_ = string.replace(path_, '/', os.sep) - abspath_ = string.replace(abspath_, '/', os.sep) - up_path_ = string.replace(up_path_, '/', os.sep) - - def strip_slash(p, drive=drive): - if p[-1] == os.sep and len(p) > 1: - p = p[:-1] - if p[0] == os.sep: - p = drive + p - return p - path = strip_slash(path_) - abspath = strip_slash(abspath_) - up_path = strip_slash(up_path_) - name = string.split(abspath, os.sep)[-1] - - assert dir.name == name, \ - "dir.name %s != expected name %s" % \ - (dir.name, name) - assert dir.path == path, \ - "dir.path %s != expected path %s" % \ - (dir.path, path) - assert str(dir) == path, \ - "str(dir) %s != expected path %s" % \ - (str(dir), path) - assert dir.get_abspath() == abspath, \ - "dir.abspath %s != expected absolute path %s" % \ - (dir.get_abspath(), abspath) - assert dir.up().path == up_path, \ - "dir.up().path %s != expected parent path %s" % \ - (dir.up().path, up_path) + def Dir_test(lpath, path_, abspath_, up_path_, sep=sep, func=_do_Dir_test): + return func(lpath, path_, abspath_, up_path_, sep) + Dir_test('', './', sub_dir, sub) Dir_test('foo', 'foo/', sub_dir_foo, './') Dir_test('foo/bar', 'foo/bar/', sub_dir_foo_bar, 'foo/') Dir_test('/foo', '/foo/', '/foo/', '/') @@ -1374,6 +1385,109 @@ class FSTestCase(_tempdirTestCase): f.get_string(0) assert f.get_string(1) == 'baz', f.get_string(1) + def test_drive_letters(self): + """Test drive-letter look-ups""" + + test = self.test + + test.subdir('sub', ['sub', 'dir']) + + def drive_workpath(drive, dirs, test=test): + x = apply(test.workpath, dirs) + drive, path = os.path.splitdrive(x) + return 'X:' + path + + wp = drive_workpath('X:', ['']) + + if wp[-1] in (os.sep, '/'): + tmp = os.path.split(wp[:-1])[0] + else: + tmp = os.path.split(wp)[0] + + parent_tmp = os.path.split(tmp)[0] + if parent_tmp == 'X:': + parent_tmp = 'X:' + os.sep + + tmp_foo = os.path.join(tmp, 'foo') + + foo = drive_workpath('X:', ['foo']) + foo_bar = drive_workpath('X:', ['foo', 'bar']) + sub = drive_workpath('X:', ['sub', '']) + sub_dir = drive_workpath('X:', ['sub', 'dir', '']) + sub_dir_foo = drive_workpath('X:', ['sub', 'dir', 'foo', '']) + sub_dir_foo_bar = drive_workpath('X:', ['sub', 'dir', 'foo', 'bar', '']) + sub_foo = drive_workpath('X:', ['sub', 'foo', '']) + + fs = SCons.Node.FS.FS() + + seps = [os.sep] + if os.sep != '/': + seps = seps + ['/'] + + def _do_Dir_test(lpath, path_, up_path_, sep, fileSys=fs): + dir = fileSys.Dir(string.replace(lpath, '/', sep)) + + if os.sep != '/': + path_ = string.replace(path_, '/', os.sep) + up_path_ = string.replace(up_path_, '/', os.sep) + + def strip_slash(p): + if p[-1] == os.sep and len(p) > 3: + p = p[:-1] + return p + path = strip_slash(path_) + up_path = strip_slash(up_path_) + name = string.split(path, os.sep)[-1] + + assert dir.name == name, \ + "dir.name %s != expected name %s" % \ + (dir.name, name) + assert dir.path == path, \ + "dir.path %s != expected path %s" % \ + (dir.path, path) + assert str(dir) == path, \ + "str(dir) %s != expected path %s" % \ + (str(dir), path) + assert dir.up().path == up_path, \ + "dir.up().path %s != expected parent path %s" % \ + (dir.up().path, up_path) + + save_os_path = os.path + save_os_sep = os.sep + try: + import ntpath + os.path = ntpath + os.sep = '\\' + SCons.Node.FS.initialize_do_splitdrive() + SCons.Node.FS.initialize_normpath_check() + + for sep in seps: + + def Dir_test(lpath, path_, up_path_, sep=sep, func=_do_Dir_test): + return func(lpath, path_, up_path_, sep) + + Dir_test('#X:', wp, tmp) + Dir_test('X:foo', foo, wp) + Dir_test('X:foo/bar', foo_bar, foo) + Dir_test('X:/foo', 'X:/foo', 'X:/') + Dir_test('X:/foo/bar', 'X:/foo/bar/', 'X:/foo/') + Dir_test('X:..', tmp, parent_tmp) + Dir_test('X:foo/..', wp, tmp) + Dir_test('X:../foo', tmp_foo, tmp) + Dir_test('X:.', wp, tmp) + Dir_test('X:./.', wp, tmp) + Dir_test('X:foo/./bar', foo_bar, foo) + Dir_test('#X:../foo', tmp_foo, tmp) + Dir_test('#X:/../foo', tmp_foo, tmp) + Dir_test('#X:foo/bar', foo_bar, foo) + Dir_test('#X:/foo/bar', foo_bar, foo) + Dir_test('#X:/', wp, tmp) + finally: + os.path = save_os_path + os.sep = save_os_sep + SCons.Node.FS.initialize_do_splitdrive() + SCons.Node.FS.initialize_normpath_check() + def test_target_from_source(self): """Test the method for generating target nodes from sources""" fs = self.fs @@ -1426,13 +1540,7 @@ class FSTestCase(_tempdirTestCase): above_path = apply(os.path.join, ['..']*len(dirs) + ['above']) above = d2.Dir(above_path) - # Note that the rel_path() method is not used right now, but we're - # leaving it commented out and disabling the unit here because - # it would be a shame to have to recreate the logic (or remember - # that it's buried in a long-past code checkin) if we ever need to - # resurrect it. - - def DO_NOT_test_rel_path(self): + def test_rel_path(self): """Test the rel_path() method""" test = self.test fs = self.fs @@ -1669,10 +1777,10 @@ class DirTestCase(_tempdirTestCase): check(s, ['src/b1']) s = b1_b2_b1_b2.srcdir_list() - check(s, []) + check(s, ['src/b1/b2']) s = b1_b2_b1_b2_sub.srcdir_list() - check(s, []) + check(s, ['src/b1/b2/sub']) def test_srcdir_duplicate(self): """Test the Dir.srcdir_duplicate() method @@ -1978,6 +2086,291 @@ class FileTestCase(_tempdirTestCase): +class GlobTestCase(_tempdirTestCase): + def setUp(self): + _tempdirTestCase.setUp(self) + + fs = SCons.Node.FS.FS() + self.fs = fs + + # Make entries on disk that will not have Nodes, so we can verify + # the behavior of looking for things on disk. + self.test.write('disk-aaa', "disk-aaa\n") + self.test.write('disk-bbb', "disk-bbb\n") + self.test.write('disk-ccc', "disk-ccc\n") + self.test.subdir('disk-sub') + self.test.write(['disk-sub', 'disk-ddd'], "disk-sub/disk-ddd\n") + self.test.write(['disk-sub', 'disk-eee'], "disk-sub/disk-eee\n") + self.test.write(['disk-sub', 'disk-fff'], "disk-sub/disk-fff\n") + + # Make some entries that have both Nodes and on-disk entries, + # so we can verify what we do with + self.test.write('both-aaa', "both-aaa\n") + self.test.write('both-bbb', "both-bbb\n") + self.test.write('both-ccc', "both-ccc\n") + self.test.subdir('both-sub1') + self.test.write(['both-sub1', 'both-ddd'], "both-sub1/both-ddd\n") + self.test.write(['both-sub1', 'both-eee'], "both-sub1/both-eee\n") + self.test.write(['both-sub1', 'both-fff'], "both-sub1/both-fff\n") + self.test.subdir('both-sub2') + self.test.write(['both-sub2', 'both-ddd'], "both-sub2/both-ddd\n") + self.test.write(['both-sub2', 'both-eee'], "both-sub2/both-eee\n") + self.test.write(['both-sub2', 'both-fff'], "both-sub2/both-fff\n") + + self.both_aaa = fs.File('both-aaa') + self.both_bbb = fs.File('both-bbb') + self.both_ccc = fs.File('both-ccc') + self.both_sub1 = fs.Dir('both-sub1') + self.both_sub1_both_ddd = self.both_sub1.File('both-ddd') + self.both_sub1_both_eee = self.both_sub1.File('both-eee') + self.both_sub1_both_fff = self.both_sub1.File('both-fff') + self.both_sub2 = fs.Dir('both-sub2') + self.both_sub2_both_ddd = self.both_sub2.File('both-ddd') + self.both_sub2_both_eee = self.both_sub2.File('both-eee') + self.both_sub2_both_fff = self.both_sub2.File('both-fff') + + # Make various Nodes (that don't have on-disk entries) so we + # can verify how we match them. + self.ggg = fs.File('ggg') + self.hhh = fs.File('hhh') + self.iii = fs.File('iii') + self.subdir1 = fs.Dir('subdir1') + self.subdir1_jjj = self.subdir1.File('jjj') + self.subdir1_kkk = self.subdir1.File('kkk') + self.subdir1_lll = self.subdir1.File('lll') + self.subdir2 = fs.Dir('subdir2') + self.subdir2_jjj = self.subdir2.File('jjj') + self.subdir2_kkk = self.subdir2.File('kkk') + self.subdir2_lll = self.subdir2.File('lll') + self.sub = fs.Dir('sub') + self.sub_dir3 = self.sub.Dir('dir3') + self.sub_dir3_jjj = self.sub_dir3.File('jjj') + self.sub_dir3_kkk = self.sub_dir3.File('kkk') + self.sub_dir3_lll = self.sub_dir3.File('lll') + + + def do_cases(self, cases, **kwargs): + + # First, execute all of the cases with string=True and verify + # that we get the expected strings returned. We do this first + # so the Glob() calls don't add Nodes to the self.fs file system + # hierarchy. + + import copy + strings_kwargs = copy.copy(kwargs) + strings_kwargs['strings'] = True + for input, string_expect, node_expect in cases: + r = apply(self.fs.Glob, (input,), strings_kwargs) + r.sort() + assert r == string_expect, "Glob(%s, strings=True) expected %s, got %s" % (input, string_expect, r) + + # Now execute all of the cases without string=True and look for + # the expected Nodes to be returned. If we don't have a list of + # actual expected Nodes, that means we're expecting a search for + # on-disk-only files to have returned some newly-created nodes. + # Verify those by running the list through str() before comparing + # them with the expected list of strings. + for input, string_expect, node_expect in cases: + r = apply(self.fs.Glob, (input,), kwargs) + if node_expect: + r.sort(lambda a,b: cmp(a.path, b.path)) + result = node_expect + else: + r = map(str, r) + r.sort() + result = string_expect + assert r == result, "Glob(%s) expected %s, got %s" % (input, map(str, result), map(str, r)) + + def test_exact_match(self): + """Test globbing for exact Node matches""" + join = os.path.join + + cases = ( + ('ggg', ['ggg'], [self.ggg]), + + ('subdir1', ['subdir1'], [self.subdir1]), + + ('subdir1/jjj', [join('subdir1', 'jjj')], [self.subdir1_jjj]), + + ('disk-aaa', ['disk-aaa'], None), + + ('disk-sub', ['disk-sub'], None), + + ('both-aaa', ['both-aaa'], []), + ) + + self.do_cases(cases) + + def test_subdir_matches(self): + """Test globbing for exact Node matches in subdirectories""" + join = os.path.join + + cases = ( + ('*/jjj', + [join('subdir1', 'jjj'), join('subdir2', 'jjj')], + [self.subdir1_jjj, self.subdir2_jjj]), + + ('*/disk-ddd', + [join('disk-sub', 'disk-ddd')], + None), + ) + + self.do_cases(cases) + + def test_asterisk(self): + """Test globbing for simple asterisk Node matches""" + cases = ( + ('h*', + ['hhh'], + [self.hhh]), + + ('*', + ['both-aaa', 'both-bbb', 'both-ccc', + 'both-sub1', 'both-sub2', + 'ggg', 'hhh', 'iii', + 'sub', 'subdir1', 'subdir2'], + [self.both_aaa, self.both_bbb, self.both_ccc, + self.both_sub1, self.both_sub2, + self.ggg, self.hhh, self.iii, + self.sub, self.subdir1, self.subdir2]), + ) + + self.do_cases(cases, ondisk=False) + + cases = ( + ('disk-b*', + ['disk-bbb'], + None), + + ('*', + ['both-aaa', 'both-bbb', 'both-ccc', 'both-sub1', 'both-sub2', + 'disk-aaa', 'disk-bbb', 'disk-ccc', 'disk-sub', + 'ggg', 'hhh', 'iii', + 'sub', 'subdir1', 'subdir2'], + None), + ) + + self.do_cases(cases) + + def test_question_mark(self): + """Test globbing for simple question-mark Node matches""" + join = os.path.join + + cases = ( + ('ii?', + ['iii'], + [self.iii]), + + ('both-sub?/both-eee', + [join('both-sub1', 'both-eee'), join('both-sub2', 'both-eee')], + [self.both_sub1_both_eee, self.both_sub2_both_eee]), + + ('subdir?/jjj', + [join('subdir1', 'jjj'), join('subdir2', 'jjj')], + [self.subdir1_jjj, self.subdir2_jjj]), + + ('disk-cc?', + ['disk-ccc'], + None), + ) + + self.do_cases(cases) + + def test_does_not_exist(self): + """Test globbing for things that don't exist""" + + cases = ( + ('does_not_exist', [], []), + ('no_subdir/*', [], []), + ('subdir?/no_file', [], []), + ) + + self.do_cases(cases) + + def test_subdir_asterisk(self): + """Test globbing for asterisk Node matches in subdirectories""" + join = os.path.join + + cases = ( + ('*/k*', + [join('subdir1', 'kkk'), join('subdir2', 'kkk')], + [self.subdir1_kkk, self.subdir2_kkk]), + + ('both-sub?/*', + [join('both-sub1', 'both-ddd'), + join('both-sub1', 'both-eee'), + join('both-sub1', 'both-fff'), + join('both-sub2', 'both-ddd'), + join('both-sub2', 'both-eee'), + join('both-sub2', 'both-fff')], + [self.both_sub1_both_ddd, self.both_sub1_both_eee, self.both_sub1_both_fff, + self.both_sub2_both_ddd, self.both_sub2_both_eee, self.both_sub2_both_fff], + ), + + ('subdir?/*', + [join('subdir1', 'jjj'), + join('subdir1', 'kkk'), + join('subdir1', 'lll'), + join('subdir2', 'jjj'), + join('subdir2', 'kkk'), + join('subdir2', 'lll')], + [self.subdir1_jjj, self.subdir1_kkk, self.subdir1_lll, + self.subdir2_jjj, self.subdir2_kkk, self.subdir2_lll]), + + ('sub/*/*', + [join('sub', 'dir3', 'jjj'), + join('sub', 'dir3', 'kkk'), + join('sub', 'dir3', 'lll')], + [self.sub_dir3_jjj, self.sub_dir3_kkk, self.sub_dir3_lll]), + + ('*/k*', + [join('subdir1', 'kkk'), join('subdir2', 'kkk')], + None), + + ('subdir?/*', + [join('subdir1', 'jjj'), + join('subdir1', 'kkk'), + join('subdir1', 'lll'), + join('subdir2', 'jjj'), + join('subdir2', 'kkk'), + join('subdir2', 'lll')], + None), + + ('sub/*/*', + [join('sub', 'dir3', 'jjj'), + join('sub', 'dir3', 'kkk'), + join('sub', 'dir3', 'lll')], + None), + ) + + self.do_cases(cases) + + def test_subdir_question(self): + """Test globbing for question-mark Node matches in subdirectories""" + join = os.path.join + + cases = ( + ('*/?kk', + [join('subdir1', 'kkk'), join('subdir2', 'kkk')], + [self.subdir1_kkk, self.subdir2_kkk]), + + ('subdir?/l?l', + [join('subdir1', 'lll'), join('subdir2', 'lll')], + [self.subdir1_lll, self.subdir2_lll]), + + ('*/disk-?ff', + [join('disk-sub', 'disk-fff')], + None), + + ('subdir?/l?l', + [join('subdir1', 'lll'), join('subdir2', 'lll')], + None), + ) + + self.do_cases(cases) + + + class RepositoryTestCase(_tempdirTestCase): def setUp(self): @@ -2379,7 +2772,7 @@ class StringDirTestCase(unittest.TestCase): fs = SCons.Node.FS.FS(test.workpath('')) d = fs.Dir('sub', '.') - assert str(d) == 'sub' + assert str(d) == 'sub', str(d) assert d.exists() f = fs.File('file', 'sub') assert str(f) == os.path.join('sub', 'file') @@ -2913,6 +3306,7 @@ if __name__ == "__main__": FileBuildInfoTestCase, FileNodeInfoTestCase, FSTestCase, + GlobTestCase, RepositoryTestCase, ] for tclass in tclasses: |