Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 137 additions & 0 deletions src/Runtime/XSharp.VFP.Tests/DirectoryTests.prg
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
//
// Copyright (c) XSharp B.V. All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
USING System
USING System.IO
USING XUnit

BEGIN NAMESPACE XSharp.VFP.Tests

CLASS DirectoryTests
STATIC CONSTRUCTOR
XSharp.RuntimeState.Dialect := XSharpDialect.FoxPro
END CONSTRUCTOR

STATIC PRIVATE METHOD NewTempDir() AS STRING
LOCAL cDir AS STRING
cDir := System.IO.Path.Combine(System.IO.Path.GetTempPath(), "VfpDirectoryTest_" + Guid.NewGuid():ToString("N"))
System.IO.Directory.CreateDirectory(cDir)
RETURN cDir
END METHOD

STATIC PRIVATE METHOD Hide(cDir AS STRING) AS VOID
LOCAL oInfo AS System.IO.DirectoryInfo
oInfo := System.IO.DirectoryInfo{cDir}
oInfo:Attributes := (System.IO.FileAttributes) _OR((DWORD) System.IO.FileAttributes.Directory, ;
(DWORD) System.IO.FileAttributes.Hidden)
END METHOD

[Fact, Trait("Category", "File")];
METHOD DirectoryFindsAnExistingDirectory() AS VOID
LOCAL cDir AS STRING
cDir := NewTempDir()
TRY
Assert.True(Directory(cDir))
FINALLY
System.IO.Directory.Delete(cDir)
END TRY
END METHOD

[Fact, Trait("Category", "File")];
METHOD DirectoryAcceptsATrailingSeparator() AS VOID
LOCAL cDir AS STRING
cDir := NewTempDir()
TRY
Assert.True(Directory(cDir + System.IO.Path.DirectorySeparatorChar:ToString()))
FINALLY
System.IO.Directory.Delete(cDir)
END TRY
END METHOD

[Fact, Trait("Category", "File")];
METHOD DirectoryReturnsFalseForAMissingDirectory() AS VOID
Assert.False(Directory(System.IO.Path.Combine(System.IO.Path.GetTempPath(), "VfpDirectoryTest_" + Guid.NewGuid():ToString("N"))))
END METHOD

// a file is not a directory, VFP reports .F. for it
[Fact, Trait("Category", "File")];
METHOD DirectoryReturnsFalseForAFile() AS VOID
LOCAL cDir AS STRING
LOCAL cFile AS STRING
cDir := NewTempDir()
cFile := System.IO.Path.Combine(cDir, "afile.txt")
System.IO.File.WriteAllText(cFile, "x")
TRY
Assert.False(Directory(cFile))
FINALLY
System.IO.File.Delete(cFile)
System.IO.Directory.Delete(cDir)
END TRY
END METHOD

[Fact, Trait("Category", "File")];
METHOD DirectoryReturnsFalseForAnEmptyName() AS VOID
Assert.False(Directory(""))
END METHOD

[Fact, Trait("Category", "File")];
METHOD DirectoryHidesAHiddenDirectoryByDefault() AS VOID
LOCAL cDir AS STRING
cDir := NewTempDir()
Hide(cDir)
TRY
Assert.False(Directory(cDir))
FINALLY
System.IO.Directory.Delete(cDir)
END TRY
END METHOD

[Fact, Trait("Category", "File")];
METHOD DirectoryFindsAHiddenDirectoryWithFlagOne() AS VOID
LOCAL cDir AS STRING
cDir := NewTempDir()
Hide(cDir)
TRY
Assert.True(Directory(cDir, 1))
FINALLY
System.IO.Directory.Delete(cDir)
END TRY
END METHOD

// only nFlags 1 ignores the attributes, 2 behaves like 0
[Fact, Trait("Category", "File")];
METHOD DirectoryTreatsFlagsOtherThanOneAsZero() AS VOID
LOCAL cDir AS STRING
cDir := NewTempDir()
Hide(cDir)
TRY
Assert.False(Directory(cDir, 2))
FINALLY
System.IO.Directory.Delete(cDir)
END TRY
END METHOD

// Windows marks a drive root Hidden and System, VFP still reports it
[Fact, Trait("Category", "File")];
METHOD DirectoryFindsADriveRoot() AS VOID
Assert.True(Directory(System.IO.Path.GetPathRoot(Environment.SystemDirectory)))
END METHOD

[Fact, Trait("Category", "File")];
METHOD DirectoryResolvesARelativeName() AS VOID
LOCAL cName AS STRING
LOCAL cDir AS STRING
cName := "VfpDirectoryTest_" + Guid.NewGuid():ToString("N")
cDir := System.IO.Path.Combine(Environment.CurrentDirectory, cName)
System.IO.Directory.CreateDirectory(cDir)
TRY
Assert.True(Directory(cName))
FINALLY
System.IO.Directory.Delete(cDir)
END TRY
END METHOD

END CLASS
END NAMESPACE
29 changes: 28 additions & 1 deletion src/Runtime/XSharp.VFP/RuntimeCoreWrappers.prg
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,34 @@ FUNCTION File(cFileSpec AS STRING) AS LOGIC
/// <include file="VfpRuntimeDocs.xml" path="Runtimefunctions/directory/*" />
[FoxProFunction("DIRECTORY", FoxFunctionCategory.FileAndIO, FoxEngine.RuntimeCore, FoxFunctionStatus.Full, FoxCriticality.High)];
FUNCTION Directory(cDirectoryName AS STRING, nFlags := 0 AS INT) AS LOGIC
RETURN XSharp.RT.Functions.ALen(XSharp.RT.Functions.Directory(cDirectoryName)) > 0
LOCAL lFound := FALSE AS LOGIC
LOCAL cFullPath AS STRING
LOCAL oAttributes AS System.IO.FileAttributes

IF String.IsNullOrWhiteSpace(cDirectoryName)
RETURN FALSE
ENDIF

TRY
// SET DEFAULT syncs the process directory in the FoxPro dialect, so a
// relative name resolves against the VFP default directory
cFullPath := System.IO.Path.GetFullPath(cDirectoryName)
IF System.IO.Directory.Exists(cFullPath)
// only nFlags 1 ignores the attributes, and Windows marks a drive
// root Hidden and System while VFP still reports it
IF nFlags == 1 .OR. String.Compare(cFullPath, System.IO.Path.GetPathRoot(cFullPath), TRUE) == 0
lFound := TRUE
ELSE
oAttributes := System.IO.File.GetAttributes(cFullPath)
lFound := ! (oAttributes:HasFlag(System.IO.FileAttributes.Hidden) .OR. ;
oAttributes:HasFlag(System.IO.FileAttributes.System))
ENDIF
ENDIF
CATCH
lFound := FALSE
END TRY

RETURN lFound

/// <include file="VfpRuntimeDocs.xml" path="Runtimefunctions/getenv/*" />
[FoxProFunction("GETENV", FoxFunctionCategory.EnvironmentAndSystem, FoxEngine.RuntimeCore, FoxFunctionStatus.Full, FoxCriticality.Medium)];
Expand Down