Ϫf&dZddlmZddlZddlZddlZddlZddlZddlZddl Z ddl m Z ddl m Z mZmZmZmZmZmZmZmZddlmZddlmZddl mZdd lmZdd lmZmZdd l m!Z!dd l"m#Z#dd l$m%Z&e!jN Z(Gdde&Z)Gdde)Z*GddejVeZ,ejBdk7r GddZ-Gdde)Z.GddZ/GddejVeZ0GddejVeZ1edZ2Gd d!e)Z3Gd"d#e*Z4Gd$d%e)Z5Gd&d'e&Z6y)(z1 Test cases covering L{twisted.python.filepath}. ) annotationsN)pformat) IOAnyStrCallableDictListOptionalTupleTypeVarUnion)skipIf) verifyObject)NoReturn)filepath)FileMode OtherAnyStr)platform)ERROR_DIRECTORY)SynchronousTestCaseceZdZdZddZy) BytesTestCasezH Override default method implementations to support byte paths. cJtj|jdS)z< Return a temporary path, encoded as bytes. utf-8)TestCasemktempencodeselfs 9/usr/lib/python3/dist-packages/twisted/test/test_paths.pyrzBytesTestCase.mktemp'st$++G44N)returnbytes)__name__ __module__ __qualname____doc__rr!r rr"s 5r!rceZdZdZdZdZddZddZddZddZ ddZ dd Z dd Z dd Z dd Zdd ZddZddZddZddZddZddZddZddZddZy)AbstractFilePathTestsz1 Tests for L{IFilePath} implementations. file 1sfile 2ctjjtjj|jg|}|j j ||SN)ospathabspathjoincmnallappend)rpxs r _mkpathzAbstractFilePathTests._mkpath6s? GGOOBGGLL6A6 7 r!cHtj|j|yr-)r.mkdirr7rdirnames r subdirzAbstractFilePathTests.subdir;s w'(r!c4t|j|dS)Nwb)openr7r:s r subfilezAbstractFilePathTests.subfile>sLDLL'*D11r!cJtj|_tjj |j x}|_|g|_tj||jd|jd5}|j|jddd|jdd5}|j|jddd|jd|jddj|jddj|jddjtj ||_tj d|_y#1swYxYw#1swYxYw) Nsub1file1file2sub3 file3.ext1s file3.ext2s file3.ext3/)timenowr.r/r0rr2r3r9r<r@write f1content f2contentcloserFilePathroot)rr2fs r setUpzAbstractFilePathTests.setUpAs+99;77dh5   G \\( # $q GGDNN # $ \\'8 , $ GGDNN # $ G Wm,224 Wm,224 Wm,224%%c* %%d+  $ $ $ $s F F FF"cj|jttj|jy)zO Instances of the path type being tested provide L{IFilePath}. N) assertTruerr IFilePathr/rs r test_verifyObjectz'AbstractFilePathTests.test_verifyObjectRs!  X%7%7CDr!c|j|jjdjdjdj|jgdy)zV Verify that the segments between two paths are correctly identified. abcrWrXrYN) assertEqualr/child segmentsFromrs r test_segmentsFromPositivez/AbstractFilePathTests.test_segmentsFromPositiveXsJ  IIOOD ! ' ' - 3 3D 9 F Ftyy Q  r!c"|jt|jjdjdjdj|jjdjdjdy)zW Verify that segmentsFrom notices when the ancestor isn't an ancestor. rWrXrYdeN) assertRaises ValueErrorr/r\r]rs r test_segmentsFromNegativez/AbstractFilePathTests.test_segmentsFromNegativeasg   IIOOD ! ' ' - 3 3D 9 F F IIOOD ! ' ' - 3 3D 9 r!c|jjDcgc]}|j}}|jt|t|jycc}w)zi Verify that walking the path gives the same result as the known file hierarchy. N)r/walkr[setr3)rfoor6s r test_walkzAbstractFilePathTests.test_walkksG "&!1 2#SXX 2 2 QTXX/ 3sA!cg}|jjdjdjd}|j}|}tjj|}||jjk7rL|j ||}tjj|}||jjk7rL|j |jDcgc]}|jc}|ycc}w)z{ L{FilePath.parents()} should return an iterator of every ancestor of the L{FilePath} in question. rWrXrYN)r/r\r.r;rOr4r[parents)rLpathobjfullpathlastpaththispathr6s r test_parentsz"AbstractFilePathTests.test_parentsss ))//$'--d399$?<<77??8,$))..( HHX Hwwx0H$))..( '//*; 6*r!cV|jjd}|jjd}|jjd}i}d||<d||<|j||d|jt|j |g|j t|j d||j t|j d|d||<|j||d|jt|dy) zK Verify that path instances are usable as dictionary keys. rCrDrN)r/r\r[listkeysassertIs assertIsNotlen)rrf1primerdictoids r test_dictionaryKeysz)AbstractFilePathTests.test_dictionaryKeyssYY__X &))//(+ YY__X &  a( glln-t4 d7<<>*1-r2 glln-a0':  a( Wq)r!c|jjd}|di}d||j<|jt|dy)z Verify that path instances are usable as dictionary keys which do not clash with their string counterparts. rChellogoodbyerN)r/r\r[r)rrrs r test_dictionaryKeyWithStringz2AbstractFilePathTests.test_dictionaryKeyWithStringsA YY__X &FH']$ Wq)r!c|jtj|jj dj y)zm Verify that children raises the appropriate exception for non-existent directories. snot realNrbrUnlistableErrorr/r\childrenrs r test_childrenNonexistentErrorz3AbstractFilePathTests.test_childrenNonexistentErrors0   $ $diiook&B&K&K r!c|jtj|jj dj y)z Verify that listdir raises the appropriate exception for attempting to list a file rather than a directory. rCNrrs r test_childrenNotDirectoryErrorz4AbstractFilePathTests.test_childrenNotDirectoryErrors- (22DIIOOH4M4V4VWr!cj|j|jjdfD]}|jt|j t |jt|j t |jt|jt y)z Verify that all times returned from the various new time functions are ints (and hopefully therefore 'high precision'). rCN)r/r\r[type getAccessTimefloatgetModificationTimegetStatusChangeTimerr5s r test_newTimesAreFloatsz,AbstractFilePathTests.test_newTimesAreFloatss DIIOOH55 CA   T!//"34e <   T!"7"7"9:E B   T!"7"7"9:E B Cr!cj|j|jjdfD]}|jt|j t |jt|j t |jt|jt y)zy Verify that all times returned from the various time functions are integers, for compatibility. rCN)r/r\r[rgetatimeintgetmtimegetctimers r test_oldTimesAreIntsz*AbstractFilePathTests.test_oldTimesAreIntssz DIIOOH55 6A   T!**,/ 5   T!**,/ 5   T!**,/ 5 6r!N)r5r#r"r#)r;r#r"None)r;r#r"zio.BufferedWriterr"r)r$r%r&r'rKrLr7r<r@rQrUr^rdrirqrzr~rrrrrrrrr(r!r r*r*.swII )2,"E   0A 5J 7+*$* XC6r!r*ceZdZdZddZy)FakeWindowsPathzV A test version of FilePath which overrides listdir to raise L{WindowsError}. c:tdd|jt)z. @raise WindowsError: always. Nz0A directory's validness was called into question)OSErrorr/rrs r rxzFakeWindowsPath.listdirs!  > II    r!N)r"z List[AnyStr])r$r%r&r'rxr(r!r rrs  r!rwin32c eZdZy) WindowsErrorN)r$r%r&r(r!r rrs r!rc`eZdZdZeej dddZddZddZ y)ListingCompatibilityTestszU These tests verify compatibility with legacy behavior of directory listing. zOnly relevant on on Windows.ct|j}|jtj|j |jt |j y)zn Verify that when a WindowsError is raised from listdir, catching WindowsError works. N)rrrbrrrr)rfwps r test_windowsErrorExceptz1ListingCompatibilityTests.test_windowsErrorExceptsB dkkm, (22CLLA , 5r!ctj|j}|jt|j y)zr Verify that in the normal case where a directory does not exist, we will get an OSError. N)rrNrrbrrrfps r test_alwaysCatchOSErrorz1ListingCompatibilityTests.test_alwaysCatchOSErrors.   t{{} - '2;;/r!ctj|j}|jt|j }t |jj}|jdt |jjj}|j|j|j||y)z Verify that the Unlistable exception raised will preserve the attributes of the previously-raised exception. originalExceptionN) rrNrrbrrr__dict__rremoversortr[)rrosed1d2s r test_keepOriginalAttributesz5ListingCompatibilityTests.test_keepOriginalAttributes"s   t{{} -5 #,,##% & %& #''00557 8     R r!Nr) r$r%r&r'rr isWindowsrrrr(r!r rr s= """$ $&DE6F60 !r!rc>eZdZdZdZd d dZd dZd dZd dZddZ y) ExplodingFilez A C{file}-alike which raises exceptions from its I/O methods and keeps track of whether it has been closed. @ivar closed: A C{bool} which is C{False} until C{close} is called, then it is C{True}. Fctz0 @raise IOError: Always raised. r)rns r rzExplodingFile.read< ir!ctrr)rwhats r rJzExplodingFile.writeBrr!cd|_y)z6 Mark the file as having been closed. TN)closedrs r rMzExplodingFile.closeHs  r!c|Sr-r(rs r __enter__zExplodingFile.__enter__Ns r!c$|jyr-)rM)rexc_type exc_value tracebacks r __exit__zExplodingFile.__exit__Qs  r!N)r)rrr"r)rr#r"rr)r"r)robjectrrrrr"r) r$r%r&r'rrrJrMrrr(r!r rr1s'F   r!rcXeZdZdZ d ddZd d dZ d dZ d d dZy)TrackingFilePathac A subclass of L{filepath.FilePath} which maintains a list of all other paths created by clonePath. @ivar trackingList: A list of all paths created by this path via C{clonePath} (which also includes paths created by methods like C{parent}, C{sibling}, C{child}, etc (and all paths subsequently created by those paths, etc). @type trackingList: C{list} of L{TrackingFilePath} @ivar openedFiles: A list of all file objects opened by this L{TrackingFilePath} or any other L{TrackingFilePath} in C{trackingList}. @type openedFiles: C{list} of C{file} Ncjtjj||||g}||_g|_yr-)rrN__init__ trackingList openedFiles)rr/ alwaysCreaters r rzTrackingFilePath.__init__gs> ""4|<  L  -/r!c|tjj||}|jj ||S)zI Override 'open' to track all files opened by this path. )rrNr?rr4rmoderPs r r?zTrackingFilePath.openws5    " "4 . "r!cZ|jDcgc]}|js|c}Scc}w)z Return a list of all L{TrackingFilePath}s associated with this L{TrackingFilePath} that have had their C{open()} method called. )rr)rr/s r openedPathszTrackingFilePath.openedPathss&"&!2!2Gd6F6FGGGs((cjt||j}|jj||S)z} Override L{filepath.FilePath.clonePath} to give the new path a reference to the same tracking list. )r)rrr4)rr/rclones r clonePathzTrackingFilePath.clonePaths/!D4E4EF   ' r!)FN)r/rrboolrzEOptional[List[Union[TrackingFilePath[str], TrackingFilePath[bytes]]]]r"rrrrr"z IO[bytes])r"z;List[Union[TrackingFilePath[str], TrackingFilePath[bytes]]]F)r/rrrr"zTrackingFilePath[OtherAnyStr])r$r%r&r'rr?rrr(r!r rrUsr(#  /// / / H DH7<  /3  & r!rcReZdZUdZded< d d dZd d dZ d d dZy)ExplodingFilePathz A specialized L{FilePath} which always returns an instance of L{ExplodingFile} from its C{open} method. @ivar fp: The L{ExplodingFile} instance most recently returned from the C{open} method. rrNcZtjj||||}||_y)aY Initialize an L{ExplodingFilePath} with a name and a reference to the @param pathName: The path name as passed to L{filepath.FilePath}. @type pathName: C{str} @param originalExploder: The L{ExplodingFilePath} to associate opened files with. @type originalExploder: L{ExplodingFilePath} N)rrNr_originalExploder)rpathNameoriginalExploders r rzExplodingFilePath.__init__s." ""42  ## !1r!c<tx}|j_|S)z Create, save, and return a new C{ExplodingFile}. @param mode: Present for signature compatibility. Ignored. @return: A new C{ExplodingFile}. )rrrrs r r?zExplodingFilePath.opens)67D " " %r!c.t||jSr-)rr)rnamers r rzExplodingFilePath.clonePaths!t'='=>>r!r-)rrrzAOptional[Union[ExplodingFilePath[str], ExplodingFilePath[bytes]]]r"rrrr)rrrrr"zfilepath.FilePath[OtherAnyStr])r$r%r&r'__annotations__rr?rr(r!r rrs\   22 2  2, 7<??/3? '?r!rTcbeZdZdZ d d dZd dZd dZd dZd dZd dZ d d Z d d Z y)PermissionsTestsz* Test Permissions and RWX classes Nc ||k7rC|d}t|dkDr|dz }|j|dt|dt|d|S)z Tests that C{first} != C{second} is false. This method tests the __ne__ method, as opposed to L{assertEqual} (C{first} == C{second}), which tests the __eq__ method. Note: this should really be part of trial r z8not not unequal (__ne__ not implemented correctly): a = z b = )rfailureExceptionr)rfirstsecondmsgs r assertNotUnequalz!PermissionsTests.assertNotUnequalsX F?{3x!|t ''(+WU^WV_N  r!c|jt5}|jdddddd|jdt j |jdt |j |jt5}|jddddd|jdt j |jddy#1swYxYw#1swYMxYw)zR Self-test for assertNotUnequal to make sure the assertion works. rrzcustom messageNz __ne__ not implemented correctly)rbAssertionErrorrassertInstr exception)raeae2s r test_testzPermissionsTests.test_tests  ~ . :"  ! !!Q(8 9 : 8#bll:KL &BLL(9:   ~ . (#  ! !!Q ' ( 8#cmm:LM a# : : ( (sC$C0$C-0C9cdD]{}dD]t}dD]m}tj|||}|j|j||j|j||j|j |ov}tjddd}|j |jxr|jxr |j y)z> L{RWX}'s constructor takes a set of booleans TFTN)rRWXr[rrJexecuterS)rrwr6rwxs r test_rwxFromBoolsz"PermissionsTests.test_rwxFromBoolss 5A" 5&5A",,q!Q/C$$SXXq1$$SYY2$$S[[!4 5 5 5ll4t, >SYY>3;;?r!c dD]}dD]}dD]z}|jtj|||tj||||jtj|||tj|||||j tjdddtjddd|j dtjdddy)z L{RWX}'s created with the same booleans are equivalent. If booleans are different, they are not equal. rTFrN)r[rrrassertNotEqual)rrrr6s r test_rwxEqNezPermissionsTests.test_rwxEqNes  XA" X&XA$$X\\!Q%:HLLAqr!c Dd d}dD]b}dD][}dD]T}tj|||}|j|j||d||dz||dzV]d|jtjdddjdy ) z L{RWX}'s shorthand string should be 'rwx' if read, write, and execute permission bits are true. If any of those permissions bits are false, the character is replaced by a '-'. c |r|Sy)N-r()valletters r getCharz3PermissionsTests.test_rwxShorthand..getChars  r!rrrr6TFzr-xN)rrrr r"r )rrr[ shorthand)rrrrr6rs r test_rwxShorthandz"PermissionsTests.test_rwxShorthand s   A" &A",,q!Q/C$$ 3'!S/9GAsOK   dE48BBDeLr!c dd}tddD]}tddD]}tddD]}d|||fz}t|d}tj|}|j |j ||d|d|j |j |j ||d|d|j |j |j||d |d |jtjd }d D].}d D]'} |jtt||| )0y)z L{Permissions}'s constructor takes a valid permissions bitmask and parsaes it to produce the correct set of boolean permissions. cLdfd tjfddDS)Nc>ttd||}|zdkDS)NS_Ir)getattrstat)rwhoconstant statModeInts r getPermissionBitzYPermissionsTests.test_permissionsFromStat.._rwxFromStat..getPermissionBit*s* 'D6#.? @#h.!33r!c30K|] }|ywr-r().0rr*r's r zRPermissionsTests.test_permissionsFromStat.._rwxFromStat../sJ$"4-Js)RWX)rr r'r r"r)rr)r)r'r*s``@r _rwxFromStatz?PermissionsTests.test_permissionsFromStat.._rwxFromStat)s# 4<<J/J r!rz%d%d%dUSRz : got user: GRPz : got group: OTHz : got other: )usergroupother)rrJrN)r)rr'r r"z filepath.RWX) rangerr Permissionsr[r7r8r9rSr%) rr1ugo chmodStringchmodValpermr'rs r test_permissionsFromStatz)PermissionsTests.test_permissionsFromStat#sY  q! A1a[ q!A"*aAY"6K";2H#//9D$$ $Xu5&-|DII;? $$ $Xu5&-}TZZLA $$ $Xu5&-}TZZLA  *##E*- CC4 Cc(:D AB C Cr!c|jtjdtjd|jtjdtjd|j tjdtjd|j dtjdy)zd Two L{Permissions}'s that are created with the same bitmask are equivalent r6rN)r[rr;rrrs r test_permissionsEqz#PermissionsTests.test_permissionsEqLs --e4h6J6J56QR h22598;O;OPU;VW H0079M9Me9TU Ax33E:;r!c tddD]}tddD]}tddD]~}tjtd|||fzd}|j |j dj d|j|j|jfD|j tjdj dy) z L{Permissions}'s shorthand string is the RWX shorthand string for its user permission bits, group permission bits, and other permission bits concatenated together, without a space. rr2z0o%d%d%drc3<K|]}|jywr-)r)r,r6s r r-z=PermissionsTests.test_permissionsShorthand..bs ./AKKM siz rwxrwx---N) r:rr;rr[rr1r7r8r9)rr<r=r>rAs r test_permissionsShorthandz*PermissionsTests.test_permissionsShorthandVs q! A1a[ q!A#//J!Q4JA0NOD$$( 48IItzz4::3V    --e4>>@+Nr!r-)rrrrrz Optional[str]r"rr) r$r%r&r'rrrrr rBrErHr(r!r rrsZ >B &-: * $ @ ?M,'CR<Or!rceZdZdZdHdZdHdZeeddHdZeeddHdZ dHdZ eeddHdZ eeddHd Z eeddHd Z dHd ZdHd ZeeddHd ZeeddHdZeeddHdZdHdZdHdZdHdZdHdZdHdZeej2dk7ddHdZeej2dk7ddHdZdHdZdHdZdHdZdHdZdHdZ dHdZ!eeddHdZ"dHd Z#dHd!Z$dHd"Z%dHd#Z&eeddHd$Z'eeddHd%Z(dHd&Z)dHd'Z*dHd(Z+dHd)Z,d*fdId+Z-dHd,Z.dHd-Z/dJd.Z0dHd/Z1eeddHd0Z2eeddHd1Z3dHd2Z4dHd3Z5dHd4Z6dHd5Z7dHd6Z8dHd7Z9dHd8Z:dHd9Z;dHd:ZdHd=Z?eejd>dHd?ZAdHd@ZBeej dAdHdBZCdHdCZDeej dAdHdDZEeejd>dHdEZFeejd>dHdFZGyG)K FilePathTestsz Test various L{FilePath} path manipulations. In particular, note that tests defined on this class instead of on the base class are only run against L{twisted.python.filepath}. c 0dD]}|jjdj||jt j t j|jjdjj|y)z L{FilePath.chmod} modifies the permissions of the passed file as expected (using C{os.stat} to check). We use some basic modes that should work everywhere (even on Windows). )mr6rBN)r/r\chmodr[r&S_IMODEr.st_moderrs r test_chmodzFilePathTests.test_chmodqsl # D IIOOG $ * *4 0    RWWTYY__W%=%B%BCKKLd  r!c|jjd}tj|j|j dtj|jdj|j dtj|jdj|j ddy)zI Create several symbolic links to files and directories. rB sub1.linkrD file2.linkssub1.file2.linkN)r/r\r.symlinkr7)rr<s r createLinkszFilePathTests.createLinks}s) 6;; \ :; 6<<).. ]0KL LL " ' 'g?Q)R r!z"Platform does not support symlinksc|jtj|jj dj|jj dj|j |jj dj |jj dj dy)zd L{FilePath.realpath} returns the path of the ultimate target of a symlink. rTs link.linkrBrDN)rVr.rUr/r\r[realpathrs r test_realpathSymlinkz"FilePathTests.test_realpathSymlinks  IIOOM * / /1N1S1S   IIOOL ) 2 2 4 IIOOG $ * *8 4 r!ctj|jjdj|jjdjtj|jjdj|jjdj|j t j |jjdjy)z L{FilePath.realpath} raises L{filepath.LinkError} if the path is a symbolic link which is part of a cycle. link1slink2N)r.rUr/r\rbr LinkErrorrXrs r test_realpathCyclicalSymlinkz*FilePathTests.test_realpathCyclicalSymlinks 499??8,11499??83L3Q3QR 499??8,11499??83L3Q3QR (,,diiooh.G.P.PQr!c|j|jjdj|jjdy)zj L{FilePath.realpath} returns the path itself if the path is not a symbolic link. rBN)r[r/r\rXrs r test_realpathNoSymlinkz$FilePathTests.test_realpathNoSymlinks7 1::VWr!cHjtjjj djjj dj djdfd }j t j|y)zT Verify that walking a path with a cyclical symlink raises an error rBsub1.loopylinkcrjjDcgc]}|jc}Scc}wr-r/rf)rhrs r iterateOverPathz?FilePathTests.test_walkCyclicalSymlink..iterateOverPaths&(, (89CHH9 99s4Nr"z List[bytes])rVr.rUr/r\rbrr\)rrds` r test_walkCyclicalSymlinkz&FilePathTests.test_walkCyclicalSymlinksr  IIOOG $ ) ) IIOOG $ * *+< = B B  : (,,o>r!c@jtjjj djjj dj djdddfd }j |y)z Verify that, after making a path with cyclical symlinks, when the supplied C{descend} predicate returns C{False}, the target is not traversed, as if it was a simple symlink. rBrac$|j Sr-rwr/s r noSymLinkszKFilePathTests.test_walkObeysDescendWithCyclicalSymlinks..noSymLinks{{}$ $r!cvjjDcgc]}|jc}Scc}w)Ndescendrc)rhrkrs r rdzPFilePathTests.test_walkObeysDescendWithCyclicalSymlinks..iterateOverPaths*(, z(JKCHHK KKs6Nr/zfilepath.FilePath[bytes]r"rre)rVr.rUr/r\rS)rrdrks` @r )test_walkObeysDescendWithCyclicalSymlinksz7FilePathTests.test_walkObeysDescendWithCyclicalSymlinkssq  IIOOG $ ) ) IIOOG $ * *+< = B B  % L )*r!c|jdd}|jj|Dcgc]}|j}}|jt |t |j ycc}w)z{ Verify that when the supplied C{descend} predicate returns C{False}, the target is not traversed. c$|j Sr-rirjs r rkz7FilePathTests.test_walkObeysDescend..noSymLinksrlr!rnNrp)rVr/rfr[rgr3)rrkrhr6s r test_walkObeysDescendz#FilePathTests.test_walkObeysDescends_  %"& !C D#SXX D D QTXX/ EsA7cd}|jjdj||jjdj}|j ||d}|jjdj|d|jjdj}|j ||y)Ns newcontentsnewscontents.tmp)r/r\ setContent getContentr[)rcontent newcontents r test_getAndSetzFilePathTests.test_getAndSets **73YY__V,779  *- **7G<YY__V,779  *-r!ctd}|jt|j|j |j j y)z If reading from the underlying file raises an exception, L{FilePath.getContent} raises that exception after closing the file. rN)rrbIOErrorrwrSrrrs r test_getContentFileClosingz(FilePathTests.test_getContentFileClosings6 r " '2==1  %r!c|jjd}|jjd}tj|j|j|j |j |j |j |j |j|j |jy)z Verify the behavior of the C{isLink} method against links and non-links. Also check that the symbolic link shares the directory property with its target. ssub4rEN)r/r\r.rUrSrwrurt)rs4s3s r test_symbolicLinkzFilePathTests.test_symbolicLinksYY__W % YY__W % 277BGG$  $ %  #  #r!c(|jjd|jjdf|jjdjd|jjdfg}|D]\}}|j||j|j d|j |j |j |j |j|jy)z Verify that symlink creates a valid symlink that is both a link and a file if its target is a file, or a directory if its target is a directory. r|s sub2.linkrFsfile3.ext1.linkzThis is a linkN)r/r\linkTorSrwr[rtrv)r targetLinkstargetlinks r test_linkTozFilePathTests.test_linkTosYY__W %tyy|'D E (..}=  23  ( =LFD MM$  OODKKM+; <   V\\^TZZ\ :   V]]_dkkm <  =r!c|jt|jjdj|jjdjd|jt|jjdj|jjdjdy)z Verify C{linkTo} fails in the following case: - the target is in a directory that doesn't exist - the target already exists rCsnosubrBrDN)rbrr/r\rrs r test_linkToErrorszFilePathTests.test_linkToErrorss   IIOOH % , , IIOOH % + +H 5   IIOOH % , , IIOOG $ * *8 4 r!c|jjdjd}d}|j|j||j d}|j |j|}|J|j|j |jd}|J|j|j |j|j|j|y)NrEfile3).foos.barsext1sext2sext3r*)r/r\rusiblingExtensionSearchsiblingExtensiontouchrsr)rf3extsf3efoundglobbeds r testMultiExtzFilePathTests.testMultiExt$s YY__W % + +H 5: 222D9:!!'* )))40    U\\^+,++D1""" W^^--.  222D9:r!ctjd}|jd|jtj|jdy)N.sfoo/bar/mon€y)rrN preauthChildrb InsecurePathrs r testPreauthChildzFilePathTests.testPreauthChild3s:   t $  # (//-Pr!c4|jjd}|j|j|j d|jt |j tjz dzd|jt |jtjz dzd|jt |jtjz dzd|j|j|j|jtj|j|j|j|jd|j|j|j|j!|j|j#|j|j%y)NsstattestrF)reraise)r/r\rr[getsizeabsrrHrrrSrsr.rrestatrurwrtrvrs r testStatCachezFilePathTests.testStatCache8sX IIOOK (   a( QZZ\DIIK78B>B QZZ\DIIK78B>B QZZ\DIIK78B>B  #  # !&&  #  $ $ # $r!c(tjtj|j}|j |jj |j |j |jj|jyr-)pickleloadsdumpsr/r[ __class__)rnewpaths r testPersistzFilePathTests.testPersistKsY,,v||DII67 ,,g.?.?@ 6r!cB|jtj|jjd|jtj|jjd|jtj|jjdy)Ns..s/etcs../..rbrrr/r\rs r testInsecureUNIXzFilePathTests.testInsecureUNIXPsb (//%H (//'J (//(Kr!rzTest will run only on Windows.c|jtj|jjd|jtj|jjdy)Ns..\..s C:randomfilerrs r testInsecureWin32zFilePathTests.testInsecureWin32UsB (//)L (///Rr!cB|jtj|jjd|jtj|jjd|jtj|jjdy)a  Windows has 'special' filenames like NUL and CON and COM1 and LPR and PRN and ... god knows what else. They can be located anywhere in the filesystem. For obvious reasons, we do not wish to normally permit access to these. sCONsC:CONzC:\CONNrrs r testInsecureWin32Whackyz%FilePathTests.testInsecureWin32WhackyZsd (//&I (//(K (//)Lr!c|jtjdtjd|jtjdtjdkD|jtjdtjdk\|jtjdtjdk\|jtjdtjdk|jtjdtjdk|jtjdtjdk|jtjdtjdk7|jtjdtjdk7|j tjdtjdk7y)NrWz)r[rrNrSrurs r testComparisonzFilePathTests.testComparisonfs **40(2C2CD2IJ ))$/(2C2CD2IIJ ))$/83D3DT3JJK ))$/83D3DT3JJK ))$/83D3DT3JJK ))$/(2C2CD2IIJ ))$/83D3DT3JJK ))$/83D3DT3JJK ))$/83D3DT3JJK **40H4E4Ed4KKLr!cr|jtj|jjddgy)zt If C{".."} is in the sequence passed to L{FilePath.descendant}, L{InsecurePath} is raised. mon€yz..N)rbrrr/rrs r test_descendantOnlyz!FilePathTests.test_descendantOnlyss.   ! !499#7#7,9M r!cl|jjd}|jd}|j|j |j |j|j d|j |j||jjy)Ns sibling_starts sibling_test) r/r\siblingr[r;basenamecreateDirectoryr r)rr5tss r testSiblingzFilePathTests.testSibling|s| IIOO, - YY ' qyy{3 8  b$)),,./r!c|jj}|j|j|jj|j |j |jj |j|j||jjjyr-) r/temporarySiblingr[r; assertNotInrrxrr parentr)rrs r testTemporarySiblingz"FilePathTests.testTemporarySiblings YY ' ' ) tyy'8'8':;  (9(9(;<  b$))**,5578r!cd}|jj|}|j|jj ||jd|y)z If L{FilePath.temporarySibling} is given an extension argument, it will produce path objects with that extension appended to their names. s.test-extensionz does not end with N)r/rrSrendswith)r testExtensionrs r test_temporarySiblingExtensionz,FilePathTests.test_temporarySiblingExtensionsT + YY ' ' 6  KKM " "= 1{{}2=2C D r!c|jj|j|jjy)z~ L{FilePath.remove} on a L{FilePath} that refers to a directory will recursively delete its contents. N)r/rrursrs r test_removeDirectoryz"FilePathTests.test_removeDirectorys/  ))+,r!c|jjd}tj|jjdj|j|j |j |j |j|jjdj y)zx For a path which is a symbolic link, L{FilePath.remove} just deletes the link, not the target. rSrBN)r/r\r.rUrrursrS)rrs r test_removeWithSymlinkz$FilePathTests.test_removeWithSymlinksz yy|, 499??7+00$))<  '  0779:r!ct|jj}tj|j }|jj ||jj|j |jt|jj}|j|j|j||y)z L{FilePath.copyTo} makes a copy of all the contents of the directory named by that L{FilePath} if it is able to do so. N) rr/rfrrNrcopyTorrr[roldPathsrnewPathss r test_copyToDirectoryz"FilePathTests.test_copyToDirectorys  ()   t{{} -   $)) ()   8,r!c|jjd}d|_t|j }|j t |j||j|jjy)z If an exception is raised while L{FilePath.copyTo} is trying to open source file to read from, the destination file is closed and the exception is raised to the caller of L{FilePath.copyTo}. snotherecy)NTr(r(r!r zAFilePathTests.test_copyToMissingDestFileClosing..r!N) r/r\rvrrrbr|rrSrr)rnosuch destinations r !test_copyToMissingDestFileClosingz/FilePathTests.test_copyToMissingDestFileClosings] ,% ( 6  '6==+>  --.r!c*t|j}tt}|jt|j ||j |jj|j |jjy)z If an exception is raised while L{FilePath.copyTo} is copying bytes between two regular files, the source and destination files are closed and the exception propagates to the caller of L{FilePath.copyTo}. N) rr__file__rbr|rrSrr)rrsources r test_copyToFileClosingz$FilePathTests.test_copyToFileClosings` ( 6 "8, '6==+>  (()  --.r!c|jttf|jj|jj dy)z L{FilePath.copyTo} fails with an OSError or IOError (depending on platform, as it propagates errors from open() and write()) when attempting to copy a directory to a child of itself. rCN)rbrr|r/rr\rs r test_copyToDirectoryItselfz(FilePathTests.test_copyToDirectoryItself5  g  0 0$))//(2K r!ctj|jjdj|jjdjt j |j }|jj||j|jdj|j|jdjDcgc]}|jc}|jdjDcgc]}|jc}ycc}wcc}w)zn Verify that copying with followLinks=True copies symlink targets instead of symlinks rBr[N) r.rUr/r\rrNrrrurwr[rr)rrr6s r test_copyToWithSymlinkz$FilePathTests.test_copyToWithSymlinks 499??7+00$))//(2K2P2PQ   t{{} -  (+2245 #%88G#4#=#=#? @aQZZ\ @#%88H#5#>#>#@ AaQZZ\ A @ As 5E/E c:tjd|jjdjt j |j }|jj|d|j|jdj|jtj|jjdjtj|jdjy)zX Verify that copying with followLinks=False copies symlinks as symlinks rBr[F followLinksN) r.rUr/r\rrNrrrSrwr[readlinkrs r test_copyToWithoutSymlinkz'FilePathTests.test_copyToWithoutSymlinks 7DIIOOH5::;   t{{} - / *1134  KK 166 7 KK*// 0 r!ctj|j}|jt|j d}|j |jtjy)zV If the source path is missing, L{FilePath.copyTo} raises L{OSError}. ssome other pathN) rrNrrbrrr[errnoENOENT)rr/excs r test_copyToMissingSourcez&FilePathTests.test_copyToMissingSourcesK  /6HI ELL1r!ct|jj}tj|j }|jj ||j |jt|jj}|j|j|j||y)zv Verify that moving an entire directory results into another directory with the same content. N) rr/rfrrNrmoveTorr[rs r test_moveTozFilePathTests.test_moveTo s  ()   t{{} -  $)) ()   8,r!ctj|j}tj|j}|j|j |j |j |j |j||j |j |j |j y)z A L{FilePath} that has been moved aside with L{FilePath.moveTo} no longer registers as existing. Its previously non-existent target exists, though, as it was created by the call to C{moveTo}. N)rrNrrrSrsrur)rrfp2s r test_moveToExistsCachez$FilePathTests.test_moveToExistsCaches   t{{} - .   $ & # %  %r!cD|j|jy)zp The assertion of test_moveToExistsCache should hold in the case of a cross-mount move. N)setUpFaultyRenamerrs r test_moveToExistsCacheCrossMountz.FilePathTests.test_moveToExistsCacheCrossMount+s   ##%r!cyr-r(r(r!r rzFilePathTests.3rr!cBtj|j}tj|j}|jd|jd||j |j d|j |j dt j|j|j |j d|j||j |j dy)a  L{FilePath.moveTo} clears its destination's status cache, such that calls to L{FilePath.getsize} after the call to C{moveTo} will report the new size, not the old one. This is a separate test from C{test_moveToExistsCache} because it is intended to cover the fact that the destination's cache is dropped; test_moveToExistsCache doesn't cover this case because (currently) a file that doesn't exist yet does not cache the fact of its non- existence. s1234s 1234567890r N) rrNrrvr[rr.rr/r)rhookrrs r test_moveToSizeCachez"FilePathTests.test_moveToSizeCache3s  t{{} - . g }%  q) + #(( + # *r!c6dfd }j|y)zn The assertion of test_moveToSizeCache should hold in the case of a cross-mount move. c&jyr-)rrsr rQz;FilePathTests.test_moveToSizeCacheCrossMount..setUpXs  " " $r!)rNr)r)rrQs` r test_moveToSizeCacheCrossMountz,FilePathTests.test_moveToSizeCacheCrossMountRs  % !!u!-r!c|jttf|jj|jj dy)z Verify error behavior of moveTo: it should raises one of OSError or IOError if you want to move a path into one of its child. It's simply the error raised by the underlying rename system call. rCN)rbrr|r/rr\rs r test_moveToErrorzFilePathTests.test_moveToError]rr!cjgdfd }tj|jtd|S)a Set up a C{os.rename} that will fail with L{errno.EXDEV} on first call. This is used to simulate a cross-device rename failure. @return: a list of pair (src, dest) of calls to C{os.rename} @rtype: C{list} of C{tuple} cj||ftdk(rttjd||S)Nz;Test-induced failure simulating cross-device rename failure)r4rrrEXDEV)srcdest invokedWithoriginalRenames r faultyRenamez5FilePathTests.setUpFaultyRename..faultyRenameqsH   T{ +;1$KKT"#t, ,r!rename)rr rr r"r)r.rpatch)rrrrs @@r rzFilePathTests.setUpFaultyRenamegs0  - 2x.r!cf|j}|j|j|y)z C{moveTo} should be able to handle C{EXDEV} error raised by C{os.rename} when trying to move a file on a different mounted filesystem. N)rrrS)rrs r test_crossMountMoveToz#FilePathTests.test_crossMountMoveTo~s. ,,.    $r!c|j}|jjd}|jjd}tj|jjdj|j|j ||j |j|j|jd|j|y)z By default, when moving a symlink, it should follow the link and actually copy the content of the linked node. rDrrCr+N) rr/r\r.rUrrurwr[rwrSrrrrs r test_crossMountMoveToWithSymlinkz.FilePathTests.test_crossMountMoveToWithSymlinks ,,. YY__X & YY__X & 499??8,11277; "  % )4  $r!c|j}|jjd}|jjd}tj|jjdj|j|j |d|j |j|j|jd|j |y)zk Verify that moveTo called with followLinks=False actually create another symlink. rDrrCFrr+N) rr/r\r.rUrrSrwr[rwr s r #test_crossMountMoveToWithoutSymlinkz1FilePathTests.test_crossMountMoveToWithoutSymlinks ,,. YY__X & YY__X & 499??8,11277; "% (  $ )4  $r!ctj|j}|j5}|j d|j |j ddddt|jd5}|j}|j|ddddy#1swYKxYw#1swYyxYw)a> L{FilePath.create} should always open (and write to) files in binary mode; line-feed octets should be unmodified. (While this test should pass on all platforms, it is only really interesting on platforms which have the concept of binary mode, i.e. Windows platforms.) b Nrb) rrNrcreater rrJr?r/rr[)rr/rPrrs r test_createBinaryModez#FilePathTests.test_createBinaryModes  / [[] a MM#qvv & GGEN $))T " *b779D   T5 ) * *   * *s.B,#B8,B58Cc|jjd}|jt|j}|j |j t j|jjd}|j d5}|jdddd|j 5}|j |jdddd|j dj|j 5}|j |jdddd|jjd}|j d5}|jdddd|j d5}|jd ddd|j d 5}|j |jd ddd|j d 5}|j |jd |jd d|jdddd|j d 5}|j |jdddd|j d5}|j |jd|jd d|jdddd|j d5}|jd|jd d|j |jd|jd d |j |jdddd|jd|j dj|}~|jttf|jy#1swY#xYw#1swYxYw#1swYxYw#1swYsxYw#1swYUxYw#1swY(xYw#1swYxYw#1swYxYw#1swY[xYw#1swYxYw)Ns nonexistentswriterrabc defr!sappendersabcasdefrsabcdefzr+rrsghis abcdefghizw+s123za+s456s123456T)r/r\rbr|r?r[rrrJrrMseek requireCreater)r nonexistentewriterrPappenderexistents r testOpenzFilePathTests.testOpens]iioon5   g{'7'7 8 %,,/+ [[  ! GGK  ! [[] 4a   QVVX{ 3 4  C [[] ,a   QVVXs + , 99??;/ ]]3  1 GGFO ]]3  1 GGFO ]]3  21   QVVXy 1 2]]4 A   QVVXy 1 FF1aL GGFO ]]3  51   QVVX| 4 5 ]]4  A   QVVXs + FF1aL GGFO ]]4 2A GGFO FF1aL   QVVXs + FF1aL   QVVXy 1 2 !!$'##%  7G,hmmrNr/r\r?rJrSrsrropenerfiles r test_openWithExplicitBinaryModez-FilePathTests.test_openWithExplicitBinaryMode s[!34T"  $t JJ{ # $  & $ $ A%%A.c|jjd}|jd}|5}|jdddd|j |j y#1swY%xYw)a Due to a bug in Python 2.7 on Windows including multiple 'b' characters in the mode passed to the built-in open() will cause an error. No matter how many 'b' modes are specified, FilePath.open() ensures that only a single 'b' character is included in the mode passed to the built-in open(). See http://bugs.python.org/issue7686 for details about the bug. smultiple-binarywbbrNr"r#s r )test_openWithRedundantExplicitBinaryModesz7FilePathTests.test_openWithRedundantExplicitBinaryModess[!34U#  $t JJ{ # $  & $ $r'ctj|j}|j|j |j |j |j y)z Check that C{filepath.FilePath.exists} correctly restat the object if an operation has occurred in the mean time. N)rrNrrursmakedirsrSrs r test_existsCachezFilePathTests.test_existsCache)sI   t{{} - %   $r!cdtjtjj |j ddd}|j |j|j|j|j|j|jy)z C{FilePath.makedirs} creates a directory at C{path}}, including recursively creating all parent directories leading up to the path. sfoosbarsbazN) rrNr.r/r1rrursr,rSrtrs r (test_makedirsMakesDirectoriesRecursivelyz6FilePathTests.test_makedirsMakesDirectoriesRecursively4sn   rww||DKKM666R S %   $  #r!c(tj|j}|j|j |j d|j |j |j |jy)z Calling C{FilePath.makedirs} with C{ignoreExistingDirectory} set to C{True} has no effect if directory does not exist. TignoreExistingDirectoryN)rrNrrursr,rSrtrs r 8test_makedirsMakesDirectoriesWithIgnoreExistingDirectoryzFFilePathTests.test_makedirsMakesDirectoriesWithIgnoreExistingDirectoryAs`   t{{} - % D 1  $  #r!c8tjtjj |j }|j |jt|j }|j|jtjy)z} C{FilePath.makedirs} throws an C{OSError} exception when called on a directory that already exists. N) rrNr.r/r1rr,rbrr[rEEXISTrrr s r (test_makedirsThrowsWithExistentDirectoryz6FilePathTests.test_makedirsThrowsWithExistentDirectoryNs^   rww||DKKM: ; %%gr{{;  %,,7r!c tj|j}|j|j |j |jd|j |j y)z C{FilePath.makedirs} succeeds when called on a directory that already exists and the c{ignoreExistingDirectory} argument is set to C{True}. Tr1N)rrNrr,rSrsrs r +test_makedirsAcceptsIgnoreExistingDirectoryz9FilePathTests.test_makedirsAcceptsIgnoreExistingDirectoryZsU   t{{} -   $ D 1  $r!c@tj|j}|j|j |j |j t|jd}|j|jtjy)z When C{FilePath.makedirs} is called with C{ignoreExistingDirectory} set to C{True} it throws an C{OSError} exceptions if path is a file. Tr1N) rrNrrrSrvrbrr,r[rr5r6s r 5test_makedirsIgnoreExistingDirectoryExistAlreadyAFilezCFilePathTests.test_makedirsIgnoreExistingDirectoryExistAlreadyAFilegso   t{{} -   $%% R[[$&  %,,7r!cdd}|jtd|tj|j }|j t |jd}|j|jtjy)z When C{FilePath.makedirs} is called with C{ignoreExistingDirectory} set to C{True} it raises an C{OSError} exception if exception errno is not EEXIST. c6ttjd)NzPermission Denied)rrEACCESrjs r faultyMakedirsz_FilePathTests.test_makedirsRaisesNonEexistErrorsIgnoreExistingDirectory..faultyMakedirs}s%,,(;< )rr?rr s r 9test_makedirsRaisesNonEexistErrorsIgnoreExistingDirectoryzGFilePathTests.test_makedirsRaisesNonEexistErrorsIgnoreExistingDirectoryvsi = 2z>2   t{{} -%% R[[$&  %,,7r!ctj|j}|jd|j |j dt |jd5}|jdddd|j |j d|j|j |j dy#1swYZxYw)z L{FilePath.changed} indicates that the L{FilePath} has changed, but does not re-read the status information from the filesystem until it is queried again via another method, such as C{getsize}. s12345rr>s12345678Nr2) rrNrrvr[rr?r/rJchanged)rrfObjs r test_changedzFilePathTests.test_changeds   t{{} - h q)"''4  $D JJ{ # $ q)  q) $ $s +CCzTest does not run on WindowscdD]x}|jjdj||j|jjdj t j |z|jjdjd|j|jjdj jdy)z Getting permissions for a file returns a L{Permissions} object for POSIX platforms (which supports separate user, group, and other permissions bits. )r6rDrBz rwxrw-r--N)r/r\rMr[getPermissionsrr;rrPs r test_getPermissions_POSIXz'FilePathTests.test_getPermissions_POSIXs# D IIOOG $ * *4 0    (7798;O;OPT;U    &&u-  IIOOG $ 3 3 5 ? ? A; r!ctj|j|j|jg}|j |gy)z While accessing L{twisted.python.filepath.FilePath.statinfo} is deprecated, the filepath itself is not. N)rrNr flushWarningstest_filePathNotDeprecatedr[)r warningInfos r rKz(FilePathTests.test_filePathNotDeprecatedsA $++-((($*I*I)JK  b)r!zTest will run only on WindowscJ|j|jjdjddD]x}|jjdj||j |jjdj t j|z|jjdjd|j |jjdj jdy)aJ Getting permissions for a file returns a L{Permissions} object in Windows. Windows requires a different test, because user permissions = group permissions = other permissions. Also, chmod may not be able to set the execute bit, so we are skipping tests that set the execute bit. rBr6)r6rLiIz r-xr-xr-xN) addCleanupr/r\rMr[rGrr;rrPs r test_getPermissions_Windowsz)FilePathTests.test_getPermissions_Windowss  066>" D IIOOG $ * *4 0    (7798;O;OPT;U    &&u-  IIOOG $ 3 3 5 ? ? A; r!c|j|jj|j|jjy)z= Ensure that a file is not a block or socket N)rur/ isBlockDeviceisSocketrs r test_whetherBlockOrSocketz'FilePathTests.test_whetherBlockOrSockets: 0023 ++-.r!c|jt|jj|jt|jj|jt|jj |jt|jj |jt|jjy)zM Verify that certain file stats are not available on Windows N)rbNotImplementedErrorr/getInodeNumber getDevicegetNumberOfHardLinks getUserID getGroupIDrs r (test_statinfoBitsNotImplementedInWindowsz6FilePathTests.test_statinfoBitsNotImplementedInWindowss -tyy/G/GH -tyy/B/BC -tyy/M/MN -tyy/B/BC -tyy/C/CDr!c|jjd}|j|fD]}|j|jt|j|j t|j|j t|j|jt|j|jt|j|jj|j|j|jj|jy)zo Verify that file inode/device/nlinks/uid/gid stats are numbers in a POSIX environment rCN) r/r\assertIsInstancerVrrWrXrYrZr[)rcr5s r test_statinfoBitsAreNumbersz)FilePathTests.test_statinfoBitsAreNumberss IIOOH %A 7A  ! !!"2"2"4c :  ! !!++- 5  ! !!"8"8":C @  ! !!++- 5  ! !!,,.# 6  7 ,,. > --/@r!cGdd}|dfd }|j_dj_jjj j jjj jjjjjjjjjjjjjy)z Verify that the right numbers come back from the right accessor methods for file inode/device/nlinks/uid/gid (in a POSIX environment) c eZdZdZdZdZdZdZy).FakeStati,irFiXN)r$r%r&st_inost_devst_nlinkst_uidst_gidr(r!r FakeStatrbsFFHFFr!ric(j_yr-)r/ _statinfo)argskwargsfakers r fakeRestatz>FilePathTests.test_statinfoNumbersAreValid..fakeRestats"&DII r!N)rlrrmrr"r)r/rrkr[rVrdrWrerXrfrYrgrZrh)rrirorns` @r test_statinfoNumbersAreValidz*FilePathTests.test_statinfoNumbersAreValids  z '& #  113T[[A ,,. < 7794==I ,,. < --/=r!Nr)rzCallable[[], None]r"r)r"zList[Tuple[str, str]])Hr$r%r&r'rQrVr symlinkSkiprYr]r_rfrqrtrzr}rrrrrrrrrgetTyperrrrrrrrrrrrrrrrrrrrrrrr r rrr r&r*r-r/r3r7r9r;r@rDrrHrKrOrSr[r_rpr(r!r rJrJis    K=>  ?   K=>R?RX K=> ?? ? K=>+?+* K=> 0? 0.& K=> $? $ K=>=?=& K=> ? " ;Q %&7 L  H   ' )+KLSMS H   ' )+KL MM M M 09  - K=> ;? ; -/& /  K=>  ?   K=>  ?  2 -&(&?K+> . . % K=> %? % K=> %? %*"L=\ '' % $ $ 8 % 88&*, H   "@A B * """$ $&EF G ,/ """$ $&EFEGE H   "@A AB A H   "@A>B>r!rJc@eZdZdZd dZd dZd dZd dZd dZd dZ y) SetContentTestsz+ Tests for L{FilePath.setContent}. c|j}tj|}|jdt |d5}|j }ddd|j dy#1swYxYw)zx Contents of the file referred to by a L{FilePath} can be written using L{FilePath.setContent}. s hello, worldrN)rrrNrvr?rr[)r pathStringr/rCcontentss r test_writezSetContentTests.test_writesg [[]   , ( *d # #tyy{H # (3 # #s A//A8ctd}|jt|jd|j |j j y)z If writing to the underlying file raises an exception, L{FilePath.setContent} raises that exception after closing the file. rsblahN)rrbr|rvrSrrrs r test_fileClosingz SetContentTests.test_fileClosing$s8 r " '2==':  %r!ct|j}|jd|jd|j}|j t |d|j |d|dy)z L{FilePath.setContent} will use a different temporary filename on each invocation, so that multiple processes, threads, or reentrant invocations will not collide with each other. salphasbetarrrN)rrrvrr[rr)rropenedSiblingss r test_nameCollisionz"SetContentTests.test_nameCollision-si dkkm , h g) ^,a0 N1-~a/@Ar!c|j}|jt|dd|j|dj j j |dj|dj |y)aA Assert that the L{TrackingFilePath} C{fp} was used to open one sibling with the given extension. @param fp: A L{TrackingFilePath} which should have been used to open file at a sibling path. @type fp: L{TrackingFilePath} @param extension: The extension the sibling path is expected to have had. @type extension: L{str} @raise: C{self.failureException} is raised if the extension of the opened file is incorrect or if not exactly one file was opened using C{fp}. rz expected exactly one opened filerz%{!r} does not end with {!r} extensionN)rr[rrS asTextModerrformat)rr extensionopeneds r _assertOneOpenedz SetContentTests._assertOneOpened=sw"! Va)KL  1I " + + - 6 6y A 3 : :q ""$i  r!c|t|j}|jd|j|dy)z L{FilePath.setContent} creates temporary files with the extension I{.new} if no alternate extension value is given. shelloz.newNrrrvrrs r test_defaultExtensionz%SetContentTests.test_defaultExtensionWs0 dkkm , h b&)r!c~t|j}|jdd|j|dy)z L{FilePath.setContent} creates temporary files with a user-supplied extension so that if it is somehow interrupted while writing them the file that it leaves behind will be identifiable. sgoodbyes-something-elsez-something-elseNrrs r test_customExtensionz$SetContentTests.test_customExtension`s4 dkkm , j"45 b"34r!Nr)rzTrackingFilePath[AnyStr]rr r"r) r$r%r&r'rxrzr}rrrr(r!r rtrts& 4&B  4*5r!rtc eZdZdZd)dZd)dZd)dZd)dZd)dZd)dZ d)dZ d)d Z d)d Z d)d Z eej d d)d Zeej d d)dZeej dd)dZeej dd)dZd)dZd)dZd)dZd)dZd)dZd)dZd)dZd)dZd)dZd)dZd)dZd)dZ d)dZ!d)dZ"d)d Z#d)d!Z$d)d"Z%d)d#Z&d)d$Z'd)d%Z(d)d&Z)d)d'Z*y()*UnicodeFilePathTestszp L{FilePath} instances should have the same internal representation as they were instantiated with. ctjd}|jt|jt y)ze L{FilePath} instantiated with a text path will return a text-mode FilePath. ./mon€yN)rrNr[rr/r rs r test_UnicodeInstantiationz.UnicodeFilePathTests.test_UnicodeInstantiationqs,   ~ . bgg,r!ctjd}|jdj}|j t |j ty)z Calling L{FilePath.child} on a text-mode L{FilePath} with a L{bytes} subpath will return a bytes-mode FilePath. ./parent-mon€y child-mon€yNrrNr\rr[rr/r#rrr\s r #test_UnicodeInstantiationBytesChildz8UnicodeFilePathTests.test_UnicodeInstantiationBytesChildysF   4 5+2245 ejj)51r!ctjd}|jd}|jt |j t y)z Calling L{FilePath.child} on a text-mode L{FilePath} with a text subpath will return a text-mode FilePath. rrN)rrNr\r[rr/r rs r %test_UnicodeInstantiationUnicodeChildz:UnicodeFilePathTests.test_UnicodeInstantiationUnicodeChilds<   4 5& ejj)3/r!ctjd}|jd}|jt |j t y)z Calling L{FilePath.preauthChild} on a text-mode L{FilePath} with a text subpath will return a text-mode FilePath. rrN)rrNrr[rr/r rs r ,test_UnicodeInstantiationUnicodePreauthChildzAUnicodeFilePathTests.test_UnicodeInstantiationUnicodePreauthChilds<   4 5 - ejj)3/r!ctjd}|jdj}|j t |j ty)z Calling L{FilePath.preauthChild} on a text-mode L{FilePath} with a bytes subpath will return a bytes-mode FilePath. rrN)rrNrrr[rr/r#rs r *test_UnicodeInstantiationBytesPreauthChildz?UnicodeFilePathTests.test_UnicodeInstantiationBytesPreauthChildsF   4 5 2 9 9 ;< ejj)51r!ctjd}|jt|jt y)zj L{FilePath} instantiated with a L{bytes} path will return a bytes-mode FilePath. ./N)rrNr[rr/r#rs r test_BytesInstantiationz,UnicodeFilePathTests.test_BytesInstantiations,   u % bgg.r!ctjd}|jdj}|j t |j ty)z Calling L{FilePath.child} on a bytes-mode L{FilePath} with a bytes subpath will return a bytes-mode FilePath. rrNrrs r !test_BytesInstantiationBytesChildz6UnicodeFilePathTests.test_BytesInstantiationBytesChildsE   u %+2245 ejj)51r!ctjdj}|jd}|j t |j ty)z Calling L{FilePath.child} on a bytes-mode L{FilePath} with a text subpath will return a text-mode FilePath. uparent-mon€yrN)rrNrr\r[rr/r rs r #test_BytesInstantiationUnicodeChildz8UnicodeFilePathTests.test_BytesInstantiationUnicodeChildsE   299; <& ejj)3/r!ctjdj}|jdj}|j t |j ty)z Calling L{FilePath.preauthChild} on a bytes-mode L{FilePath} with a bytes subpath will return a bytes-mode FilePath. rrN)rrNrrr[rr/r#rs r (test_BytesInstantiationBytesPreauthChildz=UnicodeFilePathTests.test_BytesInstantiationBytesPreauthChildsO   4;;= > 2 9 9 ;< ejj)51r!ctjdj}|jd}|j t |j ty)z Calling L{FilePath.preauthChild} on a bytes-mode L{FilePath} with a text subpath will return a text-mode FilePath. rrN)rrNrrr[rr/r rs r *test_BytesInstantiationUnicodePreauthChildz?UnicodeFilePathTests.test_BytesInstantiationUnicodePreauthChildsE   4;;= > - ejj)3/r!zTest will not work on Windowschtjd}t|}|jd|y)S The repr of a L{unicode} L{FilePath} shouldn't burst into flames. ruFilePath('/mon€y')NrrNreprr[rr reprOutputs r test_unicodereprz%UnicodeFilePathTests.test_unicodereprs.   } -"X  2J?r!ctjdj}t|}|j d|y)Q The repr of a L{bytes} L{FilePath} shouldn't burst into flames. u/parent-mon€yz%FilePath(b'/parent-mon\xe2\x82\xacy')N)rrNrrr[rs r test_bytesreprz#UnicodeFilePathTests.test_bytesreprs8   3::< ="X  CZPr!zTest only works on Windowschtjd}t|}|jd|y)rzC:\zFilePath('C:\\')Nrrs r test_unicodereprWindowsz,UnicodeFilePathTests.test_unicodereprWindowss.   v &"X  -z:r!chtjd}t|}|jd|y)rsC:\zFilePath(b'C:\\')Nrrs r test_bytesreprWindowsz*UnicodeFilePathTests.test_bytesreprWindowss.   w '"X  . ;r!ctjd}|jd}|j|djt y)zT C{globChildren} will return the same type as the pattern argument. /rrN)rrN globChildrenr]r/r#rrrs r test_mixedTypeGlobChildrenz/UnicodeFilePathTests.test_mixedTypeGlobChildrens<  s #??4( hqk..6r!ctjd}|jd}|j|djt y)z8 C{globChildren} works with L{unicode}. r*rN)rrNrr]r/r rs r test_unicodeGlobChildrenz-UnicodeFilePathTests.test_unicodeGlobChildrens<  s #??3' hqk..4r!cvtjd}|j|jty)zQ Calling C{basename} on an text- L{FilePath} returns L{unicode}. ./N)rrNr]rr rs r test_unicodeBasenamez)UnicodeFilePathTests.test_unicodeBasenames*  t $ bkkmS1r!cvtjd}|j|jty)zS Calling C{dirname} on a text-mode L{FilePath} returns L{unicode}. rN)rrNr]r;r rs r test_unicodeDirnamez(UnicodeFilePathTests.test_unicodeDirnames*  t $ bjjlC0r!ctjd}|j}|j|jt y)zk Calling C{parent} on a text-mode L{FilePath} will return a text-mode L{FilePath}. rN)rrNrr]r/r )rrrs r test_unicodeParentz'UnicodeFilePathTests.test_unicodeParent s3   t $ fkk3/r!ctjd}|jd}|j|jt y)zx A L{bytes} extension to C{temporarySibling} will mean a L{bytes} mode L{FilePath} is returned. r.txtN)rrNrr]r/r#rr tempSiblings r test_mixedTypeTemporarySiblingz3UnicodeFilePathTests.test_mixedTypeTemporarySiblings:   ~ .))'2  k..6r!ctjd}|jd}|j|jt y)z| A L{unicode} extension to C{temporarySibling} will mean a L{unicode} mode L{FilePath} is returned. u /tmp/mon€y.txtN)rrNrr]r/r rs r test_unicodeTemporarySiblingz1UnicodeFilePathTests.test_unicodeTemporarySiblings;   0 1))&1  k..4r!cDtjd}tj|jdz}|j|j d}|J|j |tj|j |j ty)z C{siblingExtensionSearch} called with L{bytes} on a L{unicode}-mode L{FilePath} will return a L{list} of L{bytes}-mode L{FilePath}s. rrrN)rrN _asTextPathrrr]r/r#rrrnewPaths r $test_mixedTypeSiblingExtensionSearchz9UnicodeFilePathTests.test_mixedTypeSiblingExtensionSearch&s   ~ .##BNN$4v$=> ++G4""" gx'8'89 gllE2r!cDtjd}tj|jdz}|j|j d}|J|j |tj|j |j ty)z C{siblingExtensionSearch} called with L{unicode} on a L{unicode}-mode L{FilePath} will return a L{list} of L{unicode}-mode L{FilePath}s. rrN)rrNrrrr]r/r rs r "test_unicodeSiblingExtensionSearchz7UnicodeFilePathTests.test_unicodeSiblingExtensionSearch4s   ~ .##BNN$4v$=> ++F3""" gx'8'89 gllC0r!c<tjd}tj|jdz}|j|j d}|j |tj|j |j ty)z C{siblingExtension} called with L{bytes} on a L{unicode}-mode L{FilePath} will return a L{bytes}-mode L{FilePath}. rrrN)rrNrrrr]r/r#rs r test_mixedTypeSiblingExtensionz3UnicodeFilePathTests.test_mixedTypeSiblingExtensionCss   ~ .##BNN$4v$=> %%g. gx'8'89 gllE2r!c<tjd}tj|jdz}|j|j d}|j |tj|j |j ty)z C{siblingExtension} called with L{unicode} on a L{unicode}-mode L{FilePath} will return a L{unicode}-mode L{FilePath}. rrN)rrNrrrr]r/r rs r test_unicodeSiblingExtensionz1UnicodeFilePathTests.test_unicodeSiblingExtensionQss   ~ .##BNN$4v$=> %%f- gx'8'89 gllC0r!ctj|j}|jtj|j}|j |j d|j |j |j d|j|j |j dd|j |j ddy)z~ C{siblingExtension} passed an empty string should return the same path, in the type of its argument. r!rN)rrNrrr[r asBytesModer)rrs notExistss r test_selfSiblingExtensionSearchz4UnicodeFilePathTests.test_selfSiblingExtensionSearch_s ""4;;=1 %%dkkm4  66s;V=O=O=QR 66r:FEr!cdtjdj|jfdj d}|j j d}|J|j|tj|j|jty)z C{childSearchPreauth} called with L{bytes} on a L{unicode}-mode L{FilePath} will return a L{bytes}-mode L{FilePath}. rc$jSr-rrsr rzGUnicodeFilePathTests.test_mixedTypeChildSearchPreauth..s  r!text.txtstext.txtN) rrNrrNr\rchildSearchPreauthr]r/r#rr\rrs @r test_mixedTypeChildSearchPreauthz5UnicodeFilePathTests.test_mixedTypeChildSearchPreauthls   ~ .  +,$ '' 4""" gx'8'89 gllE2r!cdtjdj|jfdj d}|j j d}|J|j|tj|j|jty)z C{childSearchPreauth} called with L{unicode} on a L{unicode}-mode L{FilePath} will return a L{unicode}-mode L{FilePath}. rc$jSr-rrsr rzEUnicodeFilePathTests.test_unicodeChildSearchPreauth..rr!rN) rrNrrNr\rrr]r/r rs @r test_unicodeChildSearchPreauthz3UnicodeFilePathTests.test_unicodeChildSearchPreauth}s   ~ .  +,$ '' 3""" gx'8'89 gllC0r!ctjd}|j}|j|||j |j t y)r C{asBytesMode} on a L{unicode}-mode L{FilePath} returns a new L{bytes}-mode L{FilePath}. ./tmpN)rrNrrr]r/r#rrnewfps r test_asBytesModeFromUnicodez0UnicodeFilePathTests.test_asBytesModeFromUnicodesD   w '  U# ejj%0r!ctjd}|j}|j|||j |j t y)r./tmpN)rrNrrr]r/r rs r test_asTextModeFromBytesz-UnicodeFilePathTests.test_asTextModeFromBytessC   x (  U# ejj#.r!ctjd}|j}|j|||j |j t y)zs C{asBytesMode} on a L{bytes}-mode L{FilePath} returns the same L{bytes}-mode L{FilePath}. rN)rrNrrr]r/r#rs r test_asBytesModeFromBytesz.UnicodeFilePathTests.test_asBytesModeFromBytessB   x (  b%  ejj%0r!ctjd}|j}|j|||j |j t y)zv C{asTextMode} on a L{unicode}-mode L{FilePath} returns the same L{unicode}-mode L{FilePath}. rN)rrNrrr]r/r rs r test_asTextModeFromUnicodez/UnicodeFilePathTests.test_asTextModeFromUnicodesA   w '  b%  ejj#.r!ctjd}|jd}|jd|jy)z C{asBytesMode} with an C{encoding} argument uses that encoding when coercing the L{unicode}-mode L{FilePath} to a L{bytes}-mode L{FilePath}. ☃rencoding☃N)rrNrr r/rs r 'test_asBytesModeFromUnicodeWithEncodingzrs6# TTT.#9+0B,(,,..  5H 5z6Mz6z h''/ 4<<7  #! #!L!!H<x((0<~/?))&1/?d CL]O}]O@g>)g>TU5mU5pm-8m-r!