diff --git a/src/main/java/ortus/boxlang/runtime/components/io/Directory.java b/src/main/java/ortus/boxlang/runtime/components/io/Directory.java index 506fe8861..5d48e0978 100644 --- a/src/main/java/ortus/boxlang/runtime/components/io/Directory.java +++ b/src/main/java/ortus/boxlang/runtime/components/io/Directory.java @@ -207,7 +207,6 @@ private void copy( IBoxContext context, String directory, String newDirectory, B Key.filter, filter, Key.createPath, createPath ); - System.out.println( argumentsMap.asString() ); actionsMap.get( Key.copy ).invoke( context, argumentsMap, false, Key.directoryCopy ); } diff --git a/src/main/java/ortus/boxlang/runtime/components/io/File.java b/src/main/java/ortus/boxlang/runtime/components/io/File.java index bd3e51d49..67b5cf3fb 100644 --- a/src/main/java/ortus/boxlang/runtime/components/io/File.java +++ b/src/main/java/ortus/boxlang/runtime/components/io/File.java @@ -17,21 +17,63 @@ */ package ortus.boxlang.runtime.components.io; +import java.util.HashMap; import java.util.Set; +import ortus.boxlang.runtime.BoxRuntime; +import ortus.boxlang.runtime.bifs.BIFDescriptor; import ortus.boxlang.runtime.components.Attribute; import ortus.boxlang.runtime.components.BoxComponent; import ortus.boxlang.runtime.components.Component; import ortus.boxlang.runtime.context.IBoxContext; +import ortus.boxlang.runtime.dynamic.ExpressionInterpreter; import ortus.boxlang.runtime.scopes.Key; import ortus.boxlang.runtime.types.IStruct; import ortus.boxlang.runtime.types.exceptions.BoxRuntimeException; -import ortus.boxlang.runtime.util.FileSystemUtil; import ortus.boxlang.runtime.validation.Validator; @BoxComponent public class File extends Component { + /** + * The runtime instance + */ + protected BoxRuntime runtime = BoxRuntime.getInstance(); + private final Key fileAppendKey = Key.of( "fileAppend" ); + private final Key fileCopyKey = Key.of( "fileCopy" ); + private final Key fileDeleteKey = Key.of( "fileDelete" ); + private final Key fileMoveKey = Key.of( "fileMove" ); + private final Key fileReadKey = Key.of( "fileRead" ); + private final Key fileReadBinaryKey = Key.of( "fileReadBinary" ); + private final Key fileUploadKey = Key.of( "fileUpload" ); + private final Key fileUploadAllKey = Key.of( "fileUploadAll" ); + private final Key fileWriteKey = Key.of( "fileWrite" ); + + private final HashMap actionsMap = new HashMap() { + + { + put( Key.append, + runtime.getFunctionService().getGlobalFunction( fileAppendKey ) ); + put( Key.copy, + runtime.getFunctionService().getGlobalFunction( fileCopyKey ) ); + put( Key.delete, + runtime.getFunctionService().getGlobalFunction( fileDeleteKey ) ); + put( Key.move, + runtime.getFunctionService().getGlobalFunction( fileMoveKey ) ); + put( Key.read, + runtime.getFunctionService().getGlobalFunction( fileReadKey ) ); + put( Key.readBinary, + runtime.getFunctionService().getGlobalFunction( fileReadBinaryKey ) ); + put( Key.upload, + runtime.getFunctionService().getGlobalFunction( fileUploadKey ) ); + put( Key.uploadAll, + runtime.getFunctionService().getGlobalFunction( fileUploadAllKey ) ); + put( Key.write, + runtime.getFunctionService().getGlobalFunction( fileWriteKey ) ); + + } + }; + /** * Constructor */ @@ -49,7 +91,7 @@ public File() { new Attribute( Key.output, "string" ), new Attribute( Key.addnewline, "boolean", false ), new Attribute( Key.attributes, "string" ), - new Attribute( Key.charset, "string" ), + new Attribute( Key.charset, "string", "utf-8" ), new Attribute( Key.source, "string" ), new Attribute( Key.destination, "string" ), new Attribute( Key.variable, "string" ), @@ -105,25 +147,46 @@ public File() { * */ public BodyResult _invoke( IBoxContext context, IStruct attributes, ComponentBody body, IStruct executionState ) { - Key action = Key.of( attributes.getAsString( Key.action ) ); - String file = attributes.getAsString( Key.file ); - String mode = attributes.getAsString( Key.mode ); - String output = attributes.getAsString( Key.output ); - Boolean addnewline = attributes.getAsBoolean( Key.addnewline ); - String fileAttributes = attributes.getAsString( Key.attributes ); - String charset = attributes.getAsString( Key.charset ); - String source = attributes.getAsString( Key.source ); - String destination = attributes.getAsString( Key.destination ); - String variable = attributes.getAsString( Key.variable ); - String filefield = attributes.getAsString( Key.filefield ); - String nameconflict = attributes.getAsString( Key.nameconflict ); - String accept = attributes.getAsString( Key.accept ); - String result = attributes.getAsString( Key.result ); - Boolean fixnewline = attributes.getAsBoolean( Key.fixnewline ); - Double cachedwithin = attributes.getAsDouble( Key.cachedwithin ); + Key action = Key.of( attributes.getAsString( Key.action ) ); + String output = attributes.getAsString( Key.output ); + String variable = attributes.getAsString( Key.variable ); if ( action.equals( Key.write ) ) { - write( context, file, output, addnewline, fileAttributes, charset, fixnewline, mode ); + attributes.put( Key.data, output ); + actionsMap.get( Key.write ).invoke( context, attributes, false, fileWriteKey ); + } else if ( action.equals( Key.append ) ) { + attributes.put( Key.data, output ); + actionsMap.get( Key.append ).invoke( context, attributes, false, fileAppendKey ); + } else if ( action.equals( Key.copy ) ) { + actionsMap.get( Key.copy ).invoke( context, attributes, false, fileCopyKey ); + } else if ( action.equals( Key.delete ) ) { + actionsMap.get( Key.delete ).invoke( context, attributes, false, fileDeleteKey ); + } else if ( action.equals( Key.move ) || action.equals( Key.rename ) ) { + actionsMap.get( Key.move ).invoke( context, attributes, false, fileMoveKey ); + } else if ( action.equals( Key.read ) ) { + if ( variable == null ) { + throw new BoxRuntimeException( "The [variable] attribute is required for file action [read]." ); + } + attributes.put( Key.filepath, attributes.get( Key.file ) ); + ExpressionInterpreter.setVariable( + context, + attributes.getAsString( Key.variable ), + actionsMap.get( Key.read ).invoke( context, attributes, false, fileReadKey ) + ); + } else if ( action.equals( Key.readBinary ) ) { + if ( variable == null ) { + throw new BoxRuntimeException( "The [variable] attribute is required for file action [readBinary]." ); + } + attributes.put( Key.filepath, attributes.get( Key.file ) ); + ExpressionInterpreter.setVariable( + context, + attributes.getAsString( Key.variable ), + actionsMap.get( Key.readBinary ).invoke( context, attributes, false, fileReadBinaryKey ) + ); + } else if ( action.equals( Key.upload ) ) { + throw new BoxRuntimeException( "The file action [upload] is not yet implemented in the core runtime" ); + } else if ( action.equals( Key.uploadAll ) ) { + throw new BoxRuntimeException( "The file action [uploadAll] is not yet implemented in the core runtime" ); } else { throw new BoxRuntimeException( "unimplemeted action: " + action ); } @@ -131,15 +194,4 @@ public BodyResult _invoke( IBoxContext context, IStruct attributes, ComponentBod return DEFAULT_RETURN; } - private void write( IBoxContext context, String file, String output, Boolean addnewline, String fileAttributes, String charset, Boolean fixnewline, - String mode ) { - charset = charset == null ? "UTF-8" : charset; - output = addnewline ? output + "\n" : output; - if ( fixnewline ) { - output = output.replaceAll( "\r\n", java.io.File.separator ); - } - // TODO: Apply attributes and mode - FileSystemUtil.write( file, output, charset, true ); - } - } diff --git a/src/main/java/ortus/boxlang/runtime/scopes/Key.java b/src/main/java/ortus/boxlang/runtime/scopes/Key.java index 0f83c5246..532deb94f 100644 --- a/src/main/java/ortus/boxlang/runtime/scopes/Key.java +++ b/src/main/java/ortus/boxlang/runtime/scopes/Key.java @@ -329,6 +329,7 @@ public class Key implements Comparable, Serializable { public static final Key moduleRecord = Key.of( "moduleRecord" ); public static final Key modulesDirectory = Key.of( "modulesDirectory" ); public static final Key month = Key.of( "month" ); + public static final Key move = Key.of( "move" ); public static final Key multiCharacterDelimiter = Key.of( "multiCharacterDelimiter" ); public static final Key multipart = Key.of( "multipart" ); public static final Key multipartType = Key.of( "multipartType" ); @@ -402,6 +403,8 @@ public class Key implements Comparable, Serializable { public static final Key queryTimeout = Key.of( "queryTimeout" ); public static final Key radix = Key.of( "radix" ); public static final Key Raw_Trace = Key.of( "Raw_Trace" ); + public static final Key read = Key.of( "read" ); + public static final Key readBinary = Key.of( "readBinary" ); public static final Key reapFrequency = Key.of( "reapFrequency" ); public static final Key recordCount = Key.of( "recordCount" ); public static final Key recurse = Key.of( "recurse" ); @@ -500,6 +503,8 @@ public class Key implements Comparable, Serializable { public static final Key trim = Key.of( "trim" ); public static final Key type = Key.of( "type" ); public static final Key typename = Key.of( "typename" ); + public static final Key upload = Key.of( "upload" ); + public static final Key uploadAll = Key.of( "uploadAll" ); public static final Key URL = Key.of( "URL" ); public static final Key useCustomSerializer = Key.of( "useCustomSerializer" ); public static final Key useLastAccessTimeouts = Key.of( "useLastAccessTimeouts" ); diff --git a/src/test/java/ortus/boxlang/runtime/components/io/FileTest.java b/src/test/java/ortus/boxlang/runtime/components/io/FileTest.java index 89ff03e8f..f5d0181e2 100644 --- a/src/test/java/ortus/boxlang/runtime/components/io/FileTest.java +++ b/src/test/java/ortus/boxlang/runtime/components/io/FileTest.java @@ -19,8 +19,12 @@ package ortus.boxlang.runtime.components.io; import static com.google.common.truth.Truth.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import java.io.BufferedInputStream; import java.io.IOException; +import java.net.URL; import java.nio.file.Path; import org.junit.jupiter.api.AfterAll; @@ -42,16 +46,14 @@ public class FileTest { static BoxRuntime instance; IBoxContext context; IScope variables; - static Key result = new Key( "result" ); - static String testTextFile = "src/test/resources/tmp/FileComponentTest/text.txt"; - static String testTextFileScript = "src/test/resources/tmp/FileComponentTest/textScript.txt"; - static String testTextFileCF = "src/test/resources/tmp/FileComponentTest/textCF.txt"; - static String testTextFileACF = "src/test/resources/tmp/FileComponentTest/textACF.txt"; - static String testTextFileBL = "src/test/resources/tmp/FileComponentTest/textBL.txt"; - static String testTextFile2 = "src/test/resources/tmp/FileComponentTest/nested/path/text2.txt"; - static String testNestedFile = "src/test/resources/tmp/FileComponentTest/nested/path/text.txt"; - static String testBinaryFile = "src/test/resources/tmp/FileComponentTest/test.jpg"; - static String tmpDirectory = "src/test/resources/tmp/FileComponentTest"; + static Key result = new Key( "result" ); + static String tmpDirectory = "src/test/resources/tmp/FileComponentTest"; + static String testTextFile = tmpDirectory + "/text.txt"; + static String testTextFile2 = tmpDirectory + "/nested/path/text2.txt"; + static String testNestedFile = tmpDirectory + "/nested/path/text.txt"; + static String testURLFile = "https://raw.githubusercontent.com/ColdBox/coldbox-platform/development/license.txt"; + static String testURLImage = "https://ortus-public.s3.amazonaws.com/logos/ortus-medium.jpg"; + static String testBinaryFile = tmpDirectory + "/test.jpg"; @BeforeAll public static void setUp() { @@ -69,13 +71,15 @@ public static void teardown() throws IOException { public void setupEach() { context = new ScriptingRequestBoxContext( instance.getRuntimeContext() ); variables = context.getScopeNearby( VariablesScope.name ); - if ( !FileSystemUtil.exists( tmpDirectory ) ) { - FileSystemUtil.createDirectory( tmpDirectory ); + if ( FileSystemUtil.exists( tmpDirectory ) ) { + FileSystemUtil.deleteDirectory( tmpDirectory, true ); } + FileSystemUtil.createDirectory( tmpDirectory ); } @Test - public void testTextFileWrite() throws IOException { + public void testTextFileWriteCF() throws IOException { + assertFalse( FileSystemUtil.exists( testTextFile ) ); variables.put( Key.of( "testFile" ), Path.of( testTextFile ).toAbsolutePath().toString() ); instance.executeSource( """ @@ -89,54 +93,311 @@ public void testTextFileWrite() throws IOException { @Test public void testTextFileWriteBL() throws IOException { - variables.put( Key.of( "testFile" ), Path.of( testTextFileBL ).toAbsolutePath().toString() ); + assertFalse( FileSystemUtil.exists( testTextFile ) ); + variables.put( Key.of( "testFile" ), Path.of( testTextFile ).toAbsolutePath().toString() ); instance.executeSource( """ """, context, BoxSourceType.BOXTEMPLATE ); - assertThat( FileSystemUtil.exists( testTextFileBL ) ).isTrue(); - assertThat( FileSystemUtil.read( testTextFileBL, ( String ) null, ( Integer ) null ) ).isEqualTo( "I am writing!" ); + assertThat( FileSystemUtil.exists( testTextFile ) ).isTrue(); + assertThat( FileSystemUtil.read( testTextFile, ( String ) null, ( Integer ) null ) ).isEqualTo( "I am writing!" ); } @Test public void testTextFileWriteScript() throws IOException { - variables.put( Key.of( "testFile" ), Path.of( testTextFileScript ).toAbsolutePath().toString() ); + assertFalse( FileSystemUtil.exists( testTextFile ) ); + variables.put( Key.of( "testFile" ), Path.of( testTextFile ).toAbsolutePath().toString() ); instance.executeSource( """ file action="write" file="#testFile#" output="I am writing!"; """, context, BoxSourceType.BOXSCRIPT ); - assertThat( FileSystemUtil.exists( testTextFileScript ) ).isTrue(); - assertThat( FileSystemUtil.read( testTextFileScript, ( String ) null, ( Integer ) null ) ).isEqualTo( "I am writing!" ); + assertThat( FileSystemUtil.exists( testTextFile ) ).isTrue(); + assertThat( FileSystemUtil.read( testTextFile, ( String ) null, ( Integer ) null ) ).isEqualTo( "I am writing!" ); } @Test - public void testTextFileWriteCF() throws IOException { - variables.put( Key.of( "testFile" ), Path.of( testTextFileCF ).toAbsolutePath().toString() ); + public void testTextFileReadCF() throws IOException { + assertFalse( FileSystemUtil.exists( testTextFile ) ); + FileSystemUtil.write( testTextFile, "file read test!".getBytes( "UTF-8" ), true ); + + variables.put( Key.of( "testFile" ), Path.of( testTextFile ).toAbsolutePath().toString() ); instance.executeSource( """ - file action="write" file="#testFile#" output="I am writing!"; + """, - context, BoxSourceType.CFSCRIPT ); + context, BoxSourceType.CFTEMPLATE ); - assertThat( FileSystemUtil.exists( testTextFileCF ) ).isTrue(); - assertThat( FileSystemUtil.read( testTextFileCF, ( String ) null, ( Integer ) null ) ).isEqualTo( "I am writing!" ); + assertThat( FileSystemUtil.exists( testTextFile ) ).isTrue(); + assertThat( FileSystemUtil.read( testTextFile, ( String ) null, ( Integer ) null ) ).isEqualTo( "file read test!" ); } @Test - public void testTextFileWriteACF() throws IOException { - variables.put( Key.of( "testFile" ), Path.of( testTextFileACF ).toAbsolutePath().toString() ); + public void testTextFileReadBX() throws IOException { + assertFalse( FileSystemUtil.exists( testTextFile ) ); + FileSystemUtil.write( testTextFile, "file read test!".getBytes( "UTF-8" ), true ); + + variables.put( Key.of( "testFile" ), Path.of( testTextFile ).toAbsolutePath().toString() ); instance.executeSource( """ - cffile( action="write", file="#testFile#", output="I am writing!" ); + """, - context, BoxSourceType.CFSCRIPT ); + context, BoxSourceType.BOXTEMPLATE ); + + assertThat( FileSystemUtil.exists( testTextFile ) ).isTrue(); + assertThat( FileSystemUtil.read( testTextFile, ( String ) null, ( Integer ) null ) ).isEqualTo( "file read test!" ); + } + + @Test + public void testTextFileReadScript() throws IOException { + assertFalse( FileSystemUtil.exists( testTextFile ) ); + FileSystemUtil.write( testTextFile, "file read test!".getBytes( "UTF-8" ), true ); + + variables.put( Key.of( "testFile" ), Path.of( testTextFile ).toAbsolutePath().toString() ); + instance.executeSource( + """ + file action="read" file="#testFile#" variable="readVariable"; variable="readVariable" + """, + context, BoxSourceType.BOXSCRIPT ); + + assertThat( FileSystemUtil.exists( testTextFile ) ).isTrue(); + assertThat( FileSystemUtil.read( testTextFile, ( String ) null, ( Integer ) null ) ).isEqualTo( "file read test!" ); + } + + @Test + public void testFileReadBinary() throws IOException { + assertFalse( FileSystemUtil.exists( testBinaryFile ) ); + + BufferedInputStream urlStream = new BufferedInputStream( new URL( testURLImage ).openStream() ); + FileSystemUtil.write( testBinaryFile, urlStream.readAllBytes(), true ); + + variables.put( Key.of( "testFile" ), Path.of( testBinaryFile ).toAbsolutePath().toString() ); + instance.executeSource( + """ + file action="readBinary" file="#testFile#" variable="readVariable"; + """, + context, BoxSourceType.BOXSCRIPT ); + + Object result = variables.get( Key.of( "readVariable" ) ); + assertTrue( result instanceof byte[] ); + } + + @Test + public void testFileDelete() throws IOException { + assertFalse( FileSystemUtil.exists( testTextFile ) ); + FileSystemUtil.write( testTextFile, "file read test!".getBytes( "UTF-8" ), true ); + + assertTrue( FileSystemUtil.exists( testTextFile ) ); + + variables.put( Key.of( "testFile" ), Path.of( testTextFile ).toAbsolutePath().toString() ); + instance.executeSource( + """ + file action="delete" file="#testFile#"; + """, + context, BoxSourceType.BOXSCRIPT ); + + assertFalse( FileSystemUtil.exists( testTextFile ) ); + } + + @Test + public void testFileDeleteCF() throws IOException { + assertFalse( FileSystemUtil.exists( testTextFile ) ); + FileSystemUtil.write( testTextFile, "file read test!".getBytes( "UTF-8" ), true ); + + assertTrue( FileSystemUtil.exists( testTextFile ) ); + + variables.put( Key.of( "testFile" ), Path.of( testTextFile ).toAbsolutePath().toString() ); + instance.executeSource( + """ + + """, + context, BoxSourceType.CFTEMPLATE ); + + assertFalse( FileSystemUtil.exists( testTextFile ) ); + } + + @Test + public void testFileDeleteBX() throws IOException { + assertFalse( FileSystemUtil.exists( testTextFile ) ); + FileSystemUtil.write( testTextFile, "file read test!".getBytes( "UTF-8" ), true ); + + assertTrue( FileSystemUtil.exists( testTextFile ) ); + + variables.put( Key.of( "testFile" ), Path.of( testTextFile ).toAbsolutePath().toString() ); + instance.executeSource( + """ + + """, + context, BoxSourceType.BOXTEMPLATE ); + + assertFalse( FileSystemUtil.exists( testTextFile ) ); + } + + @Test + public void testFileCopy() throws IOException { + assertFalse( FileSystemUtil.exists( testTextFile ) ); + FileSystemUtil.write( testTextFile, "file read test!".getBytes( "UTF-8" ), true ); + String copiedFile = tmpDirectory + "/copied-file.txt"; + + assertTrue( FileSystemUtil.exists( testTextFile ) ); + assertFalse( FileSystemUtil.exists( copiedFile ) ); + + variables.put( Key.of( "testFile" ), Path.of( testTextFile ).toAbsolutePath().toString() ); + variables.put( Key.of( "newFile" ), Path.of( copiedFile ).toAbsolutePath().toString() ); + instance.executeSource( + """ + file action="copy" source="#testFile#" destination="#newFile#"; + """, + context, BoxSourceType.BOXSCRIPT ); + + assertTrue( FileSystemUtil.exists( testTextFile ) ); + assertTrue( FileSystemUtil.exists( copiedFile ) ); + } + + @Test + public void testFileCopyCF() throws IOException { + assertFalse( FileSystemUtil.exists( testTextFile ) ); + FileSystemUtil.write( testTextFile, "file read test!".getBytes( "UTF-8" ), true ); + String copiedFile = tmpDirectory + "/copied-file.txt"; + + assertTrue( FileSystemUtil.exists( testTextFile ) ); + assertFalse( FileSystemUtil.exists( copiedFile ) ); + + variables.put( Key.of( "testFile" ), Path.of( testTextFile ).toAbsolutePath().toString() ); + variables.put( Key.of( "newFile" ), Path.of( copiedFile ).toAbsolutePath().toString() ); + instance.executeSource( + """ + + """, + context, BoxSourceType.CFTEMPLATE ); + + assertTrue( FileSystemUtil.exists( testTextFile ) ); + assertTrue( FileSystemUtil.exists( copiedFile ) ); + } + + @Test + public void testFileCopyBX() throws IOException { + assertFalse( FileSystemUtil.exists( testTextFile ) ); + FileSystemUtil.write( testTextFile, "file read test!".getBytes( "UTF-8" ), true ); + String copiedFile = tmpDirectory + "/copied-file.txt"; + + assertTrue( FileSystemUtil.exists( testTextFile ) ); + assertFalse( FileSystemUtil.exists( copiedFile ) ); + + variables.put( Key.of( "testFile" ), Path.of( testTextFile ).toAbsolutePath().toString() ); + variables.put( Key.of( "newFile" ), Path.of( copiedFile ).toAbsolutePath().toString() ); + instance.executeSource( + """ + + """, + context, BoxSourceType.BOXTEMPLATE ); + + assertTrue( FileSystemUtil.exists( testTextFile ) ); + assertTrue( FileSystemUtil.exists( copiedFile ) ); + } + + @Test + public void testFileMove() throws IOException { + assertFalse( FileSystemUtil.exists( testTextFile ) ); + FileSystemUtil.write( testTextFile, "file read test!".getBytes( "UTF-8" ), true ); + String movedFile = tmpDirectory + "/moved-file.txt"; + + assertTrue( FileSystemUtil.exists( testTextFile ) ); + assertFalse( FileSystemUtil.exists( movedFile ) ); + + variables.put( Key.of( "testFile" ), Path.of( testTextFile ).toAbsolutePath().toString() ); + variables.put( Key.of( "newFile" ), Path.of( movedFile ).toAbsolutePath().toString() ); + instance.executeSource( + """ + file action="move" source="#testFile#" destination="#newFile#"; + """, + context, BoxSourceType.BOXSCRIPT ); + + assertFalse( FileSystemUtil.exists( testTextFile ) ); + assertTrue( FileSystemUtil.exists( movedFile ) ); + } + + @Test + public void testFileMoveCF() throws IOException { + assertFalse( FileSystemUtil.exists( testTextFile ) ); + FileSystemUtil.write( testTextFile, "file read test!".getBytes( "UTF-8" ), true ); + String movedFile = tmpDirectory + "/moved-file.txt"; + + assertTrue( FileSystemUtil.exists( testTextFile ) ); + assertFalse( FileSystemUtil.exists( movedFile ) ); + + variables.put( Key.of( "testFile" ), Path.of( testTextFile ).toAbsolutePath().toString() ); + variables.put( Key.of( "newFile" ), Path.of( movedFile ).toAbsolutePath().toString() ); + instance.executeSource( + """ + + """, + context, BoxSourceType.CFTEMPLATE ); + + assertFalse( FileSystemUtil.exists( testTextFile ) ); + assertTrue( FileSystemUtil.exists( movedFile ) ); + } + + @Test + public void testFileMoveBX() throws IOException { + assertFalse( FileSystemUtil.exists( testTextFile ) ); + FileSystemUtil.write( testTextFile, "file read test!".getBytes( "UTF-8" ), true ); + String movedFile = tmpDirectory + "/moved-file.txt"; + + assertTrue( FileSystemUtil.exists( testTextFile ) ); + assertFalse( FileSystemUtil.exists( movedFile ) ); + + variables.put( Key.of( "testFile" ), Path.of( testTextFile ).toAbsolutePath().toString() ); + variables.put( Key.of( "newFile" ), Path.of( movedFile ).toAbsolutePath().toString() ); + instance.executeSource( + """ + + """, + context, BoxSourceType.BOXTEMPLATE ); + + assertFalse( FileSystemUtil.exists( testTextFile ) ); + assertTrue( FileSystemUtil.exists( movedFile ) ); + } + + @Test + public void testFileRename() throws IOException { + assertFalse( FileSystemUtil.exists( testTextFile ) ); + FileSystemUtil.write( testTextFile, "file read test!".getBytes( "UTF-8" ), true ); + String movedFile = tmpDirectory + "/moved-file.txt"; + + assertTrue( FileSystemUtil.exists( testTextFile ) ); + assertFalse( FileSystemUtil.exists( movedFile ) ); + + variables.put( Key.of( "testFile" ), Path.of( testTextFile ).toAbsolutePath().toString() ); + variables.put( Key.of( "newFile" ), Path.of( movedFile ).toAbsolutePath().toString() ); + instance.executeSource( + """ + file action="rename" source="#testFile#" destination="#newFile#"; + """, + context, BoxSourceType.BOXSCRIPT ); + + assertFalse( FileSystemUtil.exists( testTextFile ) ); + assertTrue( FileSystemUtil.exists( movedFile ) ); + } + + @Test + public void testFileAppend() throws IOException { + assertFalse( FileSystemUtil.exists( testTextFile ) ); + FileSystemUtil.write( testTextFile, "file read test".getBytes( "UTF-8" ), true ); + + assertTrue( FileSystemUtil.exists( testTextFile ) ); + + variables.put( Key.of( "testFile" ), Path.of( testTextFile ).toAbsolutePath().toString() ); + instance.executeSource( + """ + file action="append" file="#testFile#" output="!"; + """, + context, BoxSourceType.BOXSCRIPT ); - assertThat( FileSystemUtil.exists( testTextFileACF ) ).isTrue(); - assertThat( FileSystemUtil.read( testTextFileACF, ( String ) null, ( Integer ) null ) ).isEqualTo( "I am writing!" ); + assertThat( FileSystemUtil.read( testTextFile, null, null ) ).isEqualTo( "file read test!" ); } }