mirror of
https://github.com/enso-org/enso.git
synced 2024-12-23 13:02:07 +03:00
Add Text.write
Function (#3518)
Implements https://www.pivotaltracker.com/story/show/182309026
This commit is contained in:
parent
a1bf0974ce
commit
a04825a5ce
@ -138,6 +138,7 @@
|
||||
- [Renamed `File_Format.Text` to `Plain_Text`, updated `File_Format.Delimited`
|
||||
API and added builders for customizing less common settings.][3516]
|
||||
- [Allow control of sort direction in `First` and `Last` aggregations.][3517]
|
||||
- [Implemented `Text.write`, replacing `File.write_text`.][3518]
|
||||
|
||||
[debug-shortcuts]:
|
||||
https://github.com/enso-org/enso/blob/develop/app/gui/docs/product/shortcuts.md#debug
|
||||
@ -217,6 +218,7 @@
|
||||
[3515]: https://github.com/enso-org/enso/pull/3515
|
||||
[3516]: https://github.com/enso-org/enso/pull/3516
|
||||
[3517]: https://github.com/enso-org/enso/pull/3517
|
||||
[3518]: https://github.com/enso-org/enso/pull/3518
|
||||
|
||||
#### Enso Compiler
|
||||
|
||||
|
@ -53,4 +53,4 @@ component-groups:
|
||||
- Standard.Base.Data.Vector.Vector.distinct
|
||||
- Output:
|
||||
exports:
|
||||
- Standard.Base.System.File.File.write_text
|
||||
- Standard.Base.Data.Text.Text.write
|
||||
|
@ -576,4 +576,4 @@ Unimplemented_Error.to_display_text = "An implementation is missing: " + this.me
|
||||
|
||||
example_unimplemented = Errors.unimplemented
|
||||
unimplemented : Text -> Void
|
||||
unimplemented message="" = Panic.throw (Unimplemented_Error message)
|
||||
unimplemented message="" = Panic.throw (Unimplemented_Error message)
|
||||
|
@ -1,6 +1,7 @@
|
||||
from Standard.Base import all
|
||||
|
||||
import Standard.Base.System.File.Option
|
||||
import Standard.Base.System.File.Existing_File_Behavior
|
||||
import Standard.Base.Data.Text.Matching_Mode
|
||||
import Standard.Base.Data.Text.Text_Sub_Range
|
||||
from Standard.Base.Data.Text.Encoding as Encoding_Module import Encoding
|
||||
@ -13,8 +14,10 @@ polyglot java import java.io.InputStream as Java_Input_Stream
|
||||
polyglot java import java.io.IOException
|
||||
polyglot java import java.nio.file.AccessDeniedException
|
||||
polyglot java import java.nio.file.NoSuchFileException
|
||||
polyglot java import java.nio.file.FileAlreadyExistsException
|
||||
polyglot java import java.nio.file.FileSystems
|
||||
polyglot java import java.nio.file.Path
|
||||
polyglot java import java.nio.file.StandardCopyOption
|
||||
|
||||
## ALIAS New File
|
||||
|
||||
@ -89,36 +92,6 @@ read_text path (encoding=Encoding.utf_8) (on_problems=Report_Warning) =
|
||||
_ -> Error.throw (Illegal_Argument_Error "path should be either a File or a Text")
|
||||
file.read_text encoding on_problems
|
||||
|
||||
## ALIAS Write Text File
|
||||
|
||||
Open and write to the file at the provided `path`.
|
||||
|
||||
Arguments:
|
||||
- path: The path of the file to open and read the contents of. It will
|
||||
accept a textual path or a file.
|
||||
- contents: The text to write to the file.
|
||||
- encoding: The text encoding to decode the file with. Defaults to UTF-8.
|
||||
|
||||
? Module or Instance?
|
||||
If you have a variable `file` of type `File`, we recommend calling the
|
||||
`.read_text` method on it directly, rather than using
|
||||
`File.read_text file`. The later, however, will still work.
|
||||
|
||||
> Example
|
||||
Read the `data.csv` file from the Examples project.
|
||||
|
||||
import Standard.Base.System.File
|
||||
import Standard.Examples
|
||||
|
||||
example_read = File.read_text Examples.csv_path
|
||||
write_text : (Text | File) -> Text -> Encoding -> Text
|
||||
write_text path contents (encoding=Encoding.utf_8) =
|
||||
file = case path of
|
||||
Text -> (here.new path)
|
||||
File _ -> path
|
||||
_ -> Error.throw (Illegal_Argument_Error "path should be either a File or a Text")
|
||||
file.write_text contents encoding
|
||||
|
||||
## ALIAS Current Directory
|
||||
|
||||
Returns the current working directory (CWD) of the current program.
|
||||
@ -311,20 +284,6 @@ type File
|
||||
opts = [Option.Append, Option.Create]
|
||||
this.with_output_stream opts (_.write_bytes contents)
|
||||
|
||||
## Appends a UTF-8 encoded `Text` at the end of this file.
|
||||
|
||||
Arguments:
|
||||
- contents: The UTF-8 encoded text to append to the file.
|
||||
|
||||
> Example
|
||||
Append the text "hello" to a file.
|
||||
|
||||
import Standard.Examples
|
||||
|
||||
example_append = Examples.scratch_file.append "hello"
|
||||
append : Text -> Nothing ! File_Error
|
||||
append contents = this.append_bytes contents.utf_8
|
||||
|
||||
## Writes a number of bytes into this file, replacing any existing contents.
|
||||
|
||||
Arguments:
|
||||
@ -344,27 +303,6 @@ type File
|
||||
this.with_output_stream opts (_.write_bytes contents)
|
||||
Nothing
|
||||
|
||||
## ALIAS Write Text File
|
||||
|
||||
Writes a `Text` into this file with specified encoding, replacing any
|
||||
existing contents.
|
||||
|
||||
Arguments:
|
||||
- contents: The text to write to the file.
|
||||
- encoding: The text encoding to decode the file with. Defaults to UTF-8.
|
||||
|
||||
If the file does not exist, it will be created.
|
||||
|
||||
> Example
|
||||
Write the text "hello" to a file.
|
||||
|
||||
import Standard.Examples
|
||||
|
||||
example_write = Examples.scratch_file.write "hello"
|
||||
write_text : Text -> Encoding -> Nothing ! File_Error
|
||||
write_text contents (encoding=Encoding.utf_8) =
|
||||
this.write_bytes <| contents.bytes encoding
|
||||
|
||||
## Join two path segments together.
|
||||
|
||||
Arguments:
|
||||
@ -561,12 +499,24 @@ type File
|
||||
|
||||
example_delete =
|
||||
file = Examples.data_dir / "my_file"
|
||||
file.write_text "hello"
|
||||
"hello".write file
|
||||
file.delete
|
||||
delete : Nothing ! File_Error
|
||||
delete =
|
||||
here.handle_java_exceptions this this.prim_file.delete
|
||||
|
||||
## Moves the file to the specified destination.
|
||||
|
||||
Arguments:
|
||||
- destination: the destination to move the file to.
|
||||
- replace_existing: specifies if the operation should proceed if the
|
||||
destination file already exists. Defaults to `True`.
|
||||
move_to : File -> Boolean -> Nothing ! File_Error
|
||||
move_to destination replace_existing=True =
|
||||
here.handle_java_exceptions this <| case replace_existing of
|
||||
True -> this.prim_file.move destination.prim_file StandardCopyOption.REPLACE_EXISTING
|
||||
False -> this.prim_file.move destination.prim_file
|
||||
|
||||
## Deletes the file if it exists on disk.
|
||||
|
||||
If the file is a directory, it must be empty, otherwise a `Panic` will
|
||||
@ -891,8 +841,9 @@ handle_java_exceptions file ~action =
|
||||
Converts a Java `IOException` into its Enso counterpart.
|
||||
wrap_io_exception file io_exception =
|
||||
if Java.is_instance io_exception NoSuchFileException then Error.throw (File_Not_Found file) else
|
||||
if Java.is_instance io_exception AccessDeniedException then Error.throw (Io_Error file "You do not have permission to access the file") else
|
||||
Error.throw (Io_Error file "An IO error has occurred: "+io_exception.getMessage)
|
||||
if Java.is_instance io_exception FileAlreadyExistsException then Error.throw (File_Already_Exists_Error file) else
|
||||
if Java.is_instance io_exception AccessDeniedException then Error.throw (Io_Error file "You do not have permission to access the file") else
|
||||
Error.throw (Io_Error file "An IO error has occurred: "+io_exception.getMessage)
|
||||
|
||||
## PRIVATE
|
||||
|
||||
@ -911,6 +862,9 @@ type File_Error
|
||||
- file: The file that doesn't exist.
|
||||
type File_Not_Found file
|
||||
|
||||
## Indicates that a destination file already exists.
|
||||
type File_Already_Exists_Error file
|
||||
|
||||
## A generic IO error.
|
||||
|
||||
Arguments:
|
||||
@ -925,6 +879,7 @@ type File_Error
|
||||
to_display_text = case this of
|
||||
File_Not_Found file -> "The file at " + file.path + " does not exist."
|
||||
Io_Error file msg -> msg.to_text + " (" + file.path + ")."
|
||||
File_Already_Exists_Error file -> "The file at "+file.path+" already exists."
|
||||
|
||||
|
||||
## PRIVATE
|
||||
@ -975,3 +930,29 @@ get_file path = @Builtin_Method "File.get_file"
|
||||
Gets the textual path to the user's system-defined home directory.
|
||||
user_home : Text
|
||||
user_home = @Builtin_Method "File.user_home"
|
||||
|
||||
|
||||
## Writes (or appends) the specified bytes to the specified file.
|
||||
The behavior specified in the `existing_file` parameter will be used if the
|
||||
file exists.
|
||||
|
||||
Arguments:
|
||||
- path: The path to the target file.
|
||||
- encoding: The encoding to use when writing the file.
|
||||
- on_existing_file: Specifies how to proceed if the file already exists.
|
||||
- on_problems: Specifies how to handle any encountered problems.
|
||||
|
||||
If a character cannot be converted to a byte, an `Encoding_Error` is raised.
|
||||
If `on_problems` is set to `Report_Warning` or `Ignore`, it is replaced with
|
||||
a substitute (either <20> (if Unicode) or ? depending on the encoding).
|
||||
Otherwise, the process is aborted.
|
||||
If the path to the parent location cannot be found or the filename is
|
||||
invalid, a `File_Not_Found` is raised.
|
||||
If another error occurs, such as access denied, an `Io_Error` is raised.
|
||||
Otherwise, the file is created with the encoded text written to it.
|
||||
Text.write : (File|Text) -> Encoding -> Existing_File_Behavior -> Problem_Behavior -> Nothing ! Encoding_Error | Illegal_Argument_Error | File_Not_Found | Io_Error | File_Already_Exists_Error
|
||||
Text.write path encoding=Encoding.utf_8 on_existing_file=Existing_File_Behavior.Backup on_problems=Report_Warning =
|
||||
bytes = this.bytes encoding on_problems
|
||||
file = here.new path
|
||||
on_existing_file.write file stream->
|
||||
stream.write_bytes bytes
|
||||
|
@ -0,0 +1,89 @@
|
||||
from Standard.Base import all
|
||||
|
||||
import Standard.Base.System.File.Option
|
||||
from Standard.Base.System.File import File_Already_Exists_Error, Io_Error, File_Not_Found
|
||||
|
||||
## Specifies the behavior of a write operation when the destination file
|
||||
already exists.
|
||||
type Existing_File_Behavior
|
||||
## Replace the existing file in-place, with the new file.
|
||||
|
||||
Note: There is a risk of data loss if a failure occurs during the write
|
||||
operation.
|
||||
type Overwrite
|
||||
|
||||
## Creates a backup of the existing file (by appending a `.bak` suffix to
|
||||
the name) before replacing it with the new contents.
|
||||
|
||||
Note: This requires sufficient storage to have two copies of the file.
|
||||
If an existing `.bak` file exists, it will be replaced.
|
||||
type Backup
|
||||
|
||||
## Appends data to the existing file.
|
||||
type Append
|
||||
|
||||
## If the file already exists, a `File_Already_Exists_Error` error is
|
||||
raised.
|
||||
type Error
|
||||
|
||||
## PRIVATE
|
||||
Runs the `action` which is given a file output stream and should write
|
||||
the required contents to it.
|
||||
|
||||
The handle is configured depending on the specified behavior, it may
|
||||
point to a temporary file, for example. The stream may only be used while
|
||||
the action is being executed and it should not be stored anywhere for
|
||||
later.
|
||||
|
||||
The `action` may not be run at all in case the `Error` behavior is
|
||||
selected.
|
||||
write : File -> (Output_Stream -> Nothing) -> Nothing ! File_Not_Found | Io_Error | File_Already_Exists_Error
|
||||
write file action =
|
||||
case this of
|
||||
Overwrite -> file.with_output_stream [Option.Write, Option.Create, Option.Truncate_Existing] action
|
||||
Append -> file.with_output_stream [Option.Write, Option.Create, Option.Append] action
|
||||
Error -> file.with_output_stream [Option.Write, Option.Create_New] action
|
||||
Backup -> Panic.recover [Io_Error, File_Not_Found] <|
|
||||
handle_existing_file _ =
|
||||
here.write_file_backing_up_old_one file action
|
||||
## We first attempt to write the file to the original
|
||||
destination, but if that files due to the file already
|
||||
existing, we will run the alternative algorithm which uses a
|
||||
temporary file and creates a backup.
|
||||
Panic.catch File_Already_Exists_Error handler=handle_existing_file <|
|
||||
Panic.rethrow <| file.with_output_stream [Option.Write, Option.Create_New] action
|
||||
|
||||
## PRIVATE
|
||||
write_file_backing_up_old_one : File -> (Output_Stream -> Nothing) -> Nothing ! File_Not_Found | Io_Error | File_Already_Exists_Error
|
||||
write_file_backing_up_old_one file action = Panic.recover [Io_Error, File_Not_Found] <|
|
||||
parent = file.parent
|
||||
bak_file = parent / file.name+".bak"
|
||||
go i =
|
||||
new_name = file.name + ".new" + if i == 0 then "" else "." + i.to_text
|
||||
new_file = parent / new_name
|
||||
handle_existing_file _ = go i+1
|
||||
handle_write_failure panic =
|
||||
## Since we were already inside of the write operation,
|
||||
the file must have been created, but since we failed, we need to clean it up.
|
||||
new_file.delete
|
||||
Panic.throw panic.payload.cause
|
||||
Panic.catch File_Already_Exists_Error handler=handle_existing_file <|
|
||||
Panic.catch Internal_Write_Operation_Failed handler=handle_write_failure <|
|
||||
Panic.rethrow <|
|
||||
new_file.with_output_stream [Option.Write, Option.Create_New] output_stream->
|
||||
Panic.catch Any (action output_stream) caught_panic->
|
||||
Panic.throw (Internal_Write_Operation_Failed caught_panic)
|
||||
## We ignore the file not found error, because it means that there
|
||||
is no file to back-up. This may also be caused by someone
|
||||
removing the original file during the time when we have been
|
||||
writing the new one to the temporary location. There is nothing
|
||||
to back-up anymore, but this is not a failure, so it can be
|
||||
safely ignored.
|
||||
Panic.catch File_Not_Found handler=(_->Nothing) <|
|
||||
Panic.rethrow <| file.move_to bak_file
|
||||
Panic.rethrow <| new_file.move_to file
|
||||
go 0
|
||||
|
||||
|
||||
## PRIVATE
|
||||
type Internal_Write_Operation_Failed (cause : Caught_Panic)
|
@ -1306,7 +1306,7 @@ type Table
|
||||
|
||||
example_to_csv = Examples.inventory_table.write_csv (Enso_Project.data / 'example.json')
|
||||
write_json : File.File -> Nothing
|
||||
write_json file = file.write_text this.to_json.to_text
|
||||
write_json file = this.to_json.to_text.write file
|
||||
|
||||
## UNSTABLE
|
||||
|
||||
|
@ -712,7 +712,7 @@ wrap_junit_testsuites config builder ~action =
|
||||
if config.should_output_junit then
|
||||
builder.append '</testsuites>\n'
|
||||
config.output_path.parent.create_directory
|
||||
config.output_path.write_text builder.toString
|
||||
builder.toString.write config.output_path
|
||||
|
||||
result
|
||||
|
||||
|
@ -4,6 +4,7 @@ import com.oracle.truffle.api.TruffleFile;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.CopyOption;
|
||||
import java.nio.file.OpenOption;
|
||||
|
||||
/**
|
||||
@ -89,6 +90,10 @@ public class EnsoFile {
|
||||
truffleFile.delete();
|
||||
}
|
||||
|
||||
public void move(EnsoFile target, CopyOption... options) throws IOException {
|
||||
truffleFile.move(target.truffleFile, options);
|
||||
}
|
||||
|
||||
public boolean startsWith(EnsoFile parent) {
|
||||
return truffleFile.startsWith(parent.truffleFile);
|
||||
}
|
||||
|
2
test/Table_Tests/data/transient/.gitignore
vendored
2
test/Table_Tests/data/transient/.gitignore
vendored
@ -1 +1 @@
|
||||
*.csv
|
||||
*.csv*
|
||||
|
@ -109,7 +109,7 @@ spec =
|
||||
create_file name ending_style =
|
||||
lines = ['a,b,c', 'd,e,f', '1,2,3']
|
||||
text = lines.join ending_style
|
||||
(path name).write_text text Encoding.utf_8
|
||||
text.write (path name)
|
||||
|
||||
test_file name =
|
||||
table = File.read (path name) (Delimited "," headers=True value_formatter=Nothing) Problem_Behavior.Report_Error
|
||||
@ -126,7 +126,7 @@ spec =
|
||||
test_file 'cr.csv'
|
||||
|
||||
# Currently mixed line endings are not supported.
|
||||
(path 'mixed.csv').write_text 'a,b,c\nd,e,f\r1,2,3'
|
||||
'a,b,c\nd,e,f\r1,2,3'.write (path 'mixed.csv')
|
||||
File.read (path 'mixed.csv') (Delimited "," headers=True value_formatter=Nothing) Problem_Behavior.Report_Error . should_fail_with Invalid_Row
|
||||
|
||||
Test.specify "should work with Windows-1252 encoding" <|
|
||||
|
2
test/Tests/data/transient/.gitignore
vendored
2
test/Tests/data/transient/.gitignore
vendored
@ -1 +1 @@
|
||||
*.txt
|
||||
*.txt*
|
||||
|
@ -1,6 +1,8 @@
|
||||
from Standard.Base import all
|
||||
|
||||
from Standard.Base.Data.Text.Encoding as Encoding_Module import Encoding, Encoding_Error
|
||||
import Standard.Base.System.File.Existing_File_Behavior
|
||||
from Standard.Base.System.File import File_Already_Exists_Error
|
||||
|
||||
import Standard.Test
|
||||
import Standard.Test.Problems
|
||||
@ -46,7 +48,7 @@ spec =
|
||||
f = Enso_Project.data / "short.txt"
|
||||
f.delete_if_exists
|
||||
f.exists.should_be_false
|
||||
f.write_text "Cup"
|
||||
"Cup".write f on_existing_file=Existing_File_Behavior.Overwrite
|
||||
f.with_input_stream stream->
|
||||
stream.read_byte.should_equal 67
|
||||
stream.read_byte.should_equal 117
|
||||
@ -118,18 +120,111 @@ spec =
|
||||
contents_2.should .start_with "Cupcake ipsum dolor sit amet."
|
||||
|
||||
Test.group "write operations" <|
|
||||
Test.specify "should write and append to files" <|
|
||||
f = Enso_Project.data / "work.txt"
|
||||
transient = Enso_Project.data / "transient"
|
||||
Test.specify "should allow to append to files" <|
|
||||
f = transient / "work.txt"
|
||||
f.delete_if_exists
|
||||
f.exists.should_be_false
|
||||
f.write_text "line 1!"
|
||||
"line 1!".write f on_existing_file=Existing_File_Behavior.Append
|
||||
f.exists.should_be_true
|
||||
f.read_text.should_equal "line 1!"
|
||||
f.append '\nline 2!'
|
||||
'\nline 2!'.write f on_existing_file=Existing_File_Behavior.Append
|
||||
f.read_text.should_equal 'line 1!\nline 2!'
|
||||
f.delete
|
||||
f.exists.should_be_false
|
||||
|
||||
Test.specify "should allow to overwrite files" <|
|
||||
f = transient / "work.txt"
|
||||
f.delete_if_exists
|
||||
f.exists.should_be_false
|
||||
"line 1!".write f on_existing_file=Existing_File_Behavior.Overwrite . should_equal Nothing
|
||||
f.exists.should_be_true
|
||||
f.read_text.should_equal "line 1!"
|
||||
'line 2!'.write f on_existing_file=Existing_File_Behavior.Overwrite . should_equal Nothing
|
||||
f.read_text.should_equal 'line 2!'
|
||||
f.delete
|
||||
f.exists.should_be_false
|
||||
|
||||
Test.specify "should fail if a file already exists, depending on the settings" <|
|
||||
f = transient / "work.txt"
|
||||
f.delete_if_exists
|
||||
f.exists.should_be_false
|
||||
"line 1!".write f on_existing_file=Existing_File_Behavior.Error . should_equal Nothing
|
||||
f.exists.should_be_true
|
||||
f.read_text.should_equal "line 1!"
|
||||
"line 2!".write f on_existing_file=Existing_File_Behavior.Error . should_fail_with File_Already_Exists_Error
|
||||
f.read_text.should_equal 'line 1!'
|
||||
f.delete
|
||||
f.exists.should_be_false
|
||||
|
||||
Test.specify "should create a backup when writing a file" <|
|
||||
f = transient / "work.txt"
|
||||
f.delete_if_exists
|
||||
f.exists.should_be_false
|
||||
"line 1!".write f . should_equal Nothing
|
||||
if f.exists.not then
|
||||
Test.fail "The file should have been created."
|
||||
f.read_text.should_equal "line 1!"
|
||||
|
||||
bak = transient / "work.txt.bak"
|
||||
"backup content".write bak on_existing_file=Existing_File_Behavior.Overwrite
|
||||
|
||||
n0 = transient / "work.txt.new"
|
||||
n1 = transient / "work.txt.new.1"
|
||||
n2 = transient / "work.txt.new.2"
|
||||
n3 = transient / "work.txt.new.3"
|
||||
n4 = transient / "work.txt.new.4"
|
||||
written_news = [n0, n1, n2, n4]
|
||||
written_news.each n->
|
||||
"new content".write n on_existing_file=Existing_File_Behavior.Overwrite
|
||||
n3.delete_if_exists
|
||||
|
||||
"line 2!".write f . should_equal Nothing
|
||||
f.read_text.should_equal 'line 2!'
|
||||
bak.read_text.should_equal 'line 1!'
|
||||
if n3.exists then
|
||||
Test.fail "The temporary file should have been cleaned up."
|
||||
written_news.each n->
|
||||
n.read_text . should_equal "new content"
|
||||
[f, bak, n0, n1, n2, n4].each .delete
|
||||
|
||||
Test.specify "should correctly handle failure of the write operation when working with the backup" <|
|
||||
f = transient / "work.txt"
|
||||
"OLD".write f on_existing_file=Existing_File_Behavior.Overwrite
|
||||
bak_file = transient / "work.txt.bak"
|
||||
new_file = transient / "work.txt.new"
|
||||
[bak_file, new_file].each .delete_if_exists
|
||||
|
||||
result = Panic.recover Illegal_State_Error <|
|
||||
Existing_File_Behavior.Backup.write f output_stream->
|
||||
output_stream.write_bytes "foo".utf_8
|
||||
Panic.throw (Illegal_State_Error "baz")
|
||||
output_stream.write_bytes "bar".utf_8
|
||||
result.should_fail_with Illegal_State_Error
|
||||
result.catch.message . should_equal "baz"
|
||||
f.read_text . should_equal "OLD"
|
||||
if bak_file.exists then
|
||||
Test.fail "If the operation failed, we shouldn't have even created the backup."
|
||||
if new_file.exists then
|
||||
Test.fail "The temporary file should have been cleaned up."
|
||||
|
||||
f.delete
|
||||
result2 = Panic.recover Illegal_State_Error <|
|
||||
Existing_File_Behavior.Backup.write f output_stream->
|
||||
output_stream.write_bytes "foo".utf_8
|
||||
Panic.throw (Illegal_State_Error "baz")
|
||||
output_stream.write_bytes "bar".utf_8
|
||||
result2.should_fail_with Illegal_State_Error
|
||||
result2.catch.message . should_equal "baz"
|
||||
if f.exists.not then
|
||||
Test.fail "Since we were writing to the original destination, the partially written file should have been preserved even upon failure."
|
||||
f.read_text . should_equal "foo"
|
||||
if bak_file.exists then
|
||||
Test.fail "If the operation failed, we shouldn't have even created the backup."
|
||||
if new_file.exists then
|
||||
Test.fail "The temporary file should have been cleaned up."
|
||||
f.delete
|
||||
|
||||
Test.group "folder operations" <|
|
||||
resolve files =
|
||||
base = Enso_Project.data
|
||||
|
@ -29,7 +29,7 @@ spec =
|
||||
f = Enso_Project.data / "short.txt"
|
||||
f.delete_if_exists
|
||||
f.exists.should_be_false
|
||||
f.write_text "Cup"
|
||||
"Cup".write f
|
||||
java_charset = Encoding.utf_8.to_java_charset
|
||||
f.with_input_stream [File.Option.Read] stream->
|
||||
stream.with_java_stream java_stream->
|
||||
@ -45,7 +45,7 @@ spec =
|
||||
f = Enso_Project.data / "transient" / "varying_chunks.txt"
|
||||
fragment = 'Hello 😎🚀🚧!'
|
||||
contents = 1.up_to 1000 . map _->fragment . join '\n'
|
||||
f.write_text contents
|
||||
contents.write f
|
||||
java_charset = Encoding.utf_8.to_java_charset
|
||||
|
||||
all_codepoints = Vector.new_builder
|
||||
@ -104,7 +104,7 @@ spec =
|
||||
f = Enso_Project.data / "transient" / "utf8.txt"
|
||||
encoding = Encoding.utf_8
|
||||
java_charset = encoding.to_java_charset
|
||||
f.write_text ((0.up_to 100).map _->'Hello World!' . join '\n') Encoding.utf_8
|
||||
((0.up_to 100).map _->'Hello World!' . join '\n').write f
|
||||
expected_contents = f.read_text
|
||||
contents = read_file_one_by_one f java_charset expected_contents.length
|
||||
contents.should_equal expected_contents
|
||||
|
Loading…
Reference in New Issue
Block a user