mirror of
https://github.com/enso-org/enso.git
synced 2024-11-22 22:10:15 +03:00
Add Execution Context control to Text.write (#6459)
- Adjusted `Context.is_enabled` to support default argument (moved built in so can have defaults). - Made `environment` case-insensitive. - Bug fix for play button. - Short hand to execute within an enabled context. - Forbid file writing if the Output context is disabled with a `Forbidden_Operation` error. - Add temporary file support via `File.create_temporary_file` which is deleted on exit of JVM. - Execution Context first pass in `Text.write`. - Added dry run warning. - Writes to a temporary file if disabled. - Created a `DryRunFileManager` which will create and manage the temporary files. - Added `format` dropdown to `File.read` and `Data.read`. - Renamed `JSON_File` to `JSON_Format` to be consistent. (still to unit test).
This commit is contained in:
parent
cdd0065800
commit
6b0c682b08
@ -398,6 +398,8 @@
|
||||
`Time_Of_Day`, `Time_Zone`, and `URI` to `Text`.][6404]
|
||||
- [Implemented `create_database_table` allowing upload of in-memory
|
||||
tables.][6429]
|
||||
- [Added execution context control to writing files and dry run capabilities to
|
||||
`Text.write`.][6459]
|
||||
|
||||
[debug-shortcuts]:
|
||||
https://github.com/enso-org/enso/blob/develop/app/gui/docs/product/shortcuts.md#debug
|
||||
@ -602,6 +604,7 @@
|
||||
[6404]: https://github.com/enso-org/enso/pull/6404
|
||||
[6347]: https://github.com/enso-org/enso/pull/6347
|
||||
[6429]: https://github.com/enso-org/enso/pull/6429
|
||||
[6459]: https://github.com/enso-org/enso/pull/6459
|
||||
|
||||
#### Enso Compiler
|
||||
|
||||
|
@ -157,7 +157,7 @@ trait API {
|
||||
|
||||
/// Restart the program execution.
|
||||
#[MethodInput=RecomputeInput, rpc_name="executionContext/recompute"]
|
||||
fn recompute(&self, context_id: ContextId, invalidated_expressions: InvalidatedExpressions, mode: Option<ExecutionEnvironment>) -> ();
|
||||
fn recompute(&self, context_id: ContextId, invalidated_expressions: InvalidatedExpressions, execution_environment: Option<ExecutionEnvironment>) -> ();
|
||||
|
||||
/// Obtain the full suggestions database.
|
||||
#[MethodInput=GetSuggestionsDatabaseInput, rpc_name="search/getSuggestionsDatabase"]
|
||||
|
@ -16,10 +16,9 @@ import project.Network.HTTP.Request.Request
|
||||
import project.Network.HTTP.Request_Error
|
||||
import project.Nothing.Nothing
|
||||
import project.System.File.File
|
||||
import project.System.File_Format.Auto_Detect
|
||||
import project.System.File_Format.File_Format
|
||||
|
||||
from project.Data.Boolean import Boolean, True, False
|
||||
from project.System.File_Format import Auto_Detect, File_Format, format_widget
|
||||
|
||||
## ALIAS Load, Open
|
||||
Reads a file into Enso.
|
||||
@ -56,6 +55,7 @@ from project.Data.Boolean import Boolean, True, False
|
||||
import Standard.Examples
|
||||
|
||||
example_xls_to_table = Data.read Examples.xls (Excel (Worksheet 'Dates'))
|
||||
@format format_widget
|
||||
read : Text | File -> File_Format -> Problem_Behavior -> Any ! File_Error
|
||||
read path format=Auto_Detect (on_problems=Problem_Behavior.Report_Warning) =
|
||||
File.new path . read format on_problems
|
||||
@ -81,6 +81,7 @@ read path format=Auto_Detect (on_problems=Problem_Behavior.Report_Warning) =
|
||||
import Standard.Examples
|
||||
|
||||
example_read = Data.read_text Examples.csv_path
|
||||
@encoding Encoding.default_widget
|
||||
read_text : (Text | File) -> Encoding -> Problem_Behavior -> Text
|
||||
read_text path (encoding=Encoding.utf_8) (on_problems=Problem_Behavior.Report_Warning) =
|
||||
File.new path . read_text encoding on_problems
|
||||
|
@ -9,8 +9,19 @@ polyglot java import java.nio.charset.Charset
|
||||
polyglot java import java.nio.charset.UnsupportedCharsetException
|
||||
polyglot java import org.enso.base.Text_Utils
|
||||
|
||||
from project.Metadata.Widget import Single_Choice
|
||||
from project.Metadata.Choice import Option
|
||||
import project.Metadata.Display
|
||||
|
||||
## Represents a character encoding.
|
||||
type Encoding
|
||||
## PRIVATE
|
||||
Gets the default drop down option for this encoding.
|
||||
default_widget : Single_Choice
|
||||
default_widget =
|
||||
values = [Option "UTF-8" "Encoding.utf_8", Option "ASCII" "Encoding.ascii", Option "UTF-16LE" "Encoding.utf_16_le", Option "UTF-16BE" "Encoding.utf_16_be", Option "UTF-32LE" "Encoding.utf_32_le", Option "UTF-32BE" "Encoding.utf_32_be", Option "Windows-1250" "Encoding.windows_1250", Option "Windows-1251" "Encoding.windows_1251", Option "Windows-1252" "Encoding.windows_1252", Option "Windows-1253" "Encoding.windows_1253", Option "Windows-1254" "Encoding.windows_1254", Option "Windows-1255" "Encoding.windows_1255", Option "Windows-1256" "Encoding.windows_1256", Option "Windows-1257" "Encoding.windows_1257", Option "Windows-1258" "Encoding.windows_1258"]
|
||||
Single_Choice values=values display=Display.When_Modified
|
||||
|
||||
## PRIVATE
|
||||
ADVANCED
|
||||
Get all available character sets from Java as Encodings.
|
||||
|
@ -644,6 +644,7 @@ Text.is_whitespace self =
|
||||
Get the ASCII bytes of the text "Hello".
|
||||
|
||||
"Hello".bytes (Encoding.ascii)
|
||||
@encoding Encoding.default_widget
|
||||
Text.bytes : Encoding -> Problem_Behavior -> Vector Integer
|
||||
Text.bytes self encoding on_problems=Problem_Behavior.Report_Warning =
|
||||
result = Encoding_Utils.get_bytes self (encoding . to_java_charset)
|
||||
@ -664,6 +665,7 @@ Text.bytes self encoding on_problems=Problem_Behavior.Report_Warning =
|
||||
Get the ASCII bytes of the text "Hello".
|
||||
|
||||
"Hello".bytes (Encoding.ascii)
|
||||
@encoding Encoding.default_widget
|
||||
Text.from_bytes : Vector Integer -> Encoding -> Problem_Behavior -> Text
|
||||
Text.from_bytes bytes encoding on_problems=Problem_Behavior.Report_Error =
|
||||
result = Encoding_Utils.from_bytes bytes.to_array (encoding . to_java_charset)
|
||||
|
@ -336,3 +336,16 @@ type Forbidden_Operation
|
||||
Convert the Forbidden_Operation error to a human-readable format.
|
||||
to_display_text : Text
|
||||
to_display_text self = "Forbidden operation: "+self.operation+"."
|
||||
|
||||
type Dry_Run_Operation
|
||||
## PRIVATE
|
||||
A warning that the operation has only been performed in a test mode.
|
||||
|
||||
Arguments:
|
||||
- message: The message to be displayed.
|
||||
Warning message
|
||||
|
||||
## PRIVATE
|
||||
Convert the Dry_Run_Operation to a human-readable format.
|
||||
to_display_text : Text
|
||||
to_display_text self = self.message
|
||||
|
@ -63,7 +63,7 @@ export project.Warning.Warning
|
||||
from project.Data.Boolean export Boolean, True, False
|
||||
from project.Function export all
|
||||
from project.Data.Numbers export Number, Integer, Decimal
|
||||
from project.System.File_Format export File_Format, Plain_Text_Format, Plain_Text, Bytes, Infer, Auto_Detect, JSON_File
|
||||
from project.System.File_Format export File_Format, Plain_Text_Format, Plain_Text, Bytes, Infer, Auto_Detect, JSON_Format
|
||||
|
||||
import project.Data
|
||||
import project.Data.Filter_Condition.Filter_Condition
|
||||
|
@ -1,6 +1,8 @@
|
||||
import project.Any.Any
|
||||
import project.Data.Array.Array
|
||||
import project.Data.Boolean.Boolean
|
||||
import project.Data.Text.Case.Case
|
||||
import project.Data.Text.Extensions
|
||||
import project.Data.Text.Text
|
||||
import project.Data.Vector.Vector
|
||||
import project.Errors.Common.Forbidden_Operation
|
||||
@ -159,7 +161,18 @@ type Context
|
||||
- environment: Name of the execution environment.
|
||||
- context: The context to enable.
|
||||
is_enabled : Text -> Boolean
|
||||
is_enabled self environment=Runtime.current_execution_environment = @Builtin_Method "Context.is_enabled"
|
||||
is_enabled self environment=Runtime.current_execution_environment =
|
||||
self.is_enabled_builtin (environment.to_case Case.Lower)
|
||||
|
||||
## PRIVATE
|
||||
is_enabled_builtin : Text -> Boolean
|
||||
is_enabled_builtin self environment = @Builtin_Method "Context.is_enabled_builtin"
|
||||
|
||||
## PRIVATE
|
||||
Run an action with the Context enabled.
|
||||
with_enabled : Function -> Any
|
||||
with_enabled self ~action =
|
||||
with_enabled_context self Runtime.current_execution_environment action
|
||||
|
||||
|
||||
## PRIVATE
|
||||
@ -179,7 +192,8 @@ current_execution_environment = @Builtin_Method "Runtime.current_execution_envir
|
||||
- context: The context to enable.
|
||||
- action: Action to be performed with the context enabled.
|
||||
with_enabled_context : Context -> Text -> Function -> Any
|
||||
with_enabled_context context environment=Runtime.current_execution_environment ~action = with_enabled_context_builtin context environment action
|
||||
with_enabled_context context environment=Runtime.current_execution_environment ~action =
|
||||
with_enabled_context_builtin context (environment.to_case Case.Lower) action
|
||||
|
||||
## PRIVATE
|
||||
ADVANCED
|
||||
@ -205,7 +219,8 @@ with_enabled_context_builtin context environment ~action = @Builtin_Method "Runt
|
||||
- context: The context to disable.
|
||||
- action: Action to be performed with the context disabled.
|
||||
with_disabled_context : Context -> Text -> Function -> Any
|
||||
with_disabled_context context environment=Runtime.current_execution_environment ~action = with_disabled_context_builtin context environment action
|
||||
with_disabled_context context environment=Runtime.current_execution_environment ~action =
|
||||
with_disabled_context_builtin context (environment.to_case Case.Lower) action
|
||||
|
||||
## PRIVATE
|
||||
ADVANCED
|
||||
|
@ -11,6 +11,7 @@ import project.Data.Text.Text
|
||||
import project.Data.Time.Time_Of_Day.Time_Of_Day
|
||||
import project.Data.Vector.Vector
|
||||
import project.Error.Error
|
||||
import project.Errors.Common.Forbidden_Operation
|
||||
import project.Errors.Encoding_Error.Encoding_Error
|
||||
import project.Errors.File_Error.File_Error
|
||||
import project.Errors.Illegal_Argument.Illegal_Argument
|
||||
@ -18,21 +19,23 @@ import project.Errors.Problem_Behavior.Problem_Behavior
|
||||
import project.Meta
|
||||
import project.Nothing.Nothing
|
||||
import project.Panic.Panic
|
||||
import project.Runtime.Context
|
||||
import project.Runtime.Managed_Resource.Managed_Resource
|
||||
import project.System.File.File_Access.File_Access
|
||||
import project.System.File_Format.Auto_Detect
|
||||
import project.System.File_Format.File_Format
|
||||
import project.System.File.File_Permissions.File_Permissions
|
||||
|
||||
from project.Data.Boolean import Boolean, True, False
|
||||
from project.System.File_Format import Auto_Detect, File_Format, format_widget
|
||||
|
||||
import project.Metadata.Widget
|
||||
from project.Metadata.Choice import Option
|
||||
import project.Metadata.Display
|
||||
|
||||
polyglot java import org.enso.base.DryRunFileManager
|
||||
polyglot java import org.enso.base.Encoding_Utils
|
||||
polyglot java import org.enso.base.encoding.ReportingStreamDecoder
|
||||
polyglot java import org.enso.base.encoding.ReportingStreamEncoder
|
||||
polyglot java import java.io.File as Java_File
|
||||
polyglot java import java.io.InputStream as Java_Input_Stream
|
||||
polyglot java import java.io.OutputStream as Java_Output_Stream
|
||||
polyglot java import java.nio.file.FileSystems
|
||||
@ -64,6 +67,28 @@ type File
|
||||
_ : File -> path
|
||||
_ -> Error.throw (Illegal_Argument.Error "new file should be either a File or a Text")
|
||||
|
||||
## Creates a temporary file which will be deleted when Enso exits.
|
||||
create_temporary_file : Text -> Text -> File
|
||||
create_temporary_file prefix="temp" suffix=".tmp" =
|
||||
java_file = Java_File.createTempFile prefix suffix
|
||||
java_file.deleteOnExit
|
||||
File.new java_file.getAbsolutePath
|
||||
|
||||
## PRIVATE
|
||||
Create a dry run temporary file which will be deleted when Enso exits.
|
||||
|
||||
For an absolute path the same temporary file is returned.
|
||||
If this file is a temporary file that was generated by
|
||||
`create_dry_run_file` on another file, it is returned as-is.
|
||||
create_dry_run_file : Boolean -> File ! File_Error
|
||||
create_dry_run_file self copy_original=False =
|
||||
temp_path = DryRunFileManager.getTemporaryFile self.absolute.path
|
||||
if temp_path.is_nothing then Error.throw (File_Error.IO_Error "Unable to create a temporary file.") else
|
||||
temp = File.new temp_path
|
||||
if self.exists && copy_original then
|
||||
self.copy_to temp replace_existing=True
|
||||
temp
|
||||
|
||||
## ALIAS Current Directory
|
||||
|
||||
Returns the current working directory (CWD) of the current program.
|
||||
@ -116,7 +141,27 @@ type File
|
||||
file.with_output_stream [File_Access.Create, File_Access.Write] action
|
||||
with_output_stream : Vector File_Access -> (Output_Stream -> Any ! File_Error) -> Any ! File_Error
|
||||
with_output_stream self open_options action =
|
||||
Managed_Resource.bracket (self.new_output_stream open_options) (_.close) action
|
||||
new_output_stream : File -> Vector File_Access -> Output_Stream ! File_Error
|
||||
new_output_stream file open_options =
|
||||
opts = open_options . map (_.to_java) . to_array
|
||||
stream = File_Error.handle_java_exceptions file <|
|
||||
file.output_stream_builtin opts
|
||||
## We re-wrap the File Not Found error to return the parent directory
|
||||
instead of the file itself - because the file that is being written
|
||||
may not exist and it will not be an error, it is the parent directory
|
||||
that does not exist is what prevents the write operation from
|
||||
succeeding.
|
||||
## Until #5792 properly fixes catch, we cannot catch
|
||||
`File_Error.Not_Found` specifically, so instead we catch all
|
||||
`File_Error`s and match the needed one.
|
||||
stream_2 = stream.catch File_Error error-> case error of
|
||||
File_Error.Not_Found file_path -> Error.throw (File_Error.Not_Found file_path.parent)
|
||||
_ -> stream
|
||||
resource = Managed_Resource.register stream_2 close_stream
|
||||
Output_Stream.Value file resource
|
||||
|
||||
if Context.Output.is_enabled.not then Error.throw (Forbidden_Operation.Error "File writing is forbidden as the Output context is disabled") else
|
||||
Managed_Resource.bracket (new_output_stream self open_options) (_.close) action
|
||||
|
||||
## PRIVATE
|
||||
Creates a new output stream for this file. Recommended to use
|
||||
@ -125,8 +170,8 @@ type File
|
||||
Arguments:
|
||||
- options: A vector of `File_Access` objects determining how to open
|
||||
the stream. These options set the access properties of the stream.
|
||||
output_stream : Vector File_Access -> Output_Stream
|
||||
output_stream self options = @Builtin_Method "File.output_stream"
|
||||
output_stream_builtin : Vector File_Access -> Output_Stream
|
||||
output_stream_builtin self options = @Builtin_Method "File.output_stream_builtin"
|
||||
|
||||
## PRIVATE
|
||||
Creates a new input stream for this file. Recommended to use
|
||||
@ -196,6 +241,7 @@ type File
|
||||
import Standard.Examples
|
||||
|
||||
example_xls_to_table = Examples.xls.read (Excel (Worksheet 'Dates'))
|
||||
@format format_widget
|
||||
read : File_Format -> Problem_Behavior -> Any ! File_Error
|
||||
read self format=Auto_Detect (on_problems=Problem_Behavior.Report_Warning) =
|
||||
format.read self on_problems
|
||||
@ -231,6 +277,7 @@ type File
|
||||
import Standard.Examples
|
||||
|
||||
example_read = Examples.csv.read
|
||||
@encoding Encoding.default_widget
|
||||
read_text : Encoding -> Problem_Behavior -> Text ! File_Error
|
||||
read_text self (encoding=Encoding.utf_8) (on_problems=Problem_Behavior.Report_Warning) =
|
||||
file = File.new self
|
||||
@ -366,7 +413,15 @@ type File
|
||||
example_is_directory =
|
||||
(Examples.data_dir / "my_directory") . create_directory
|
||||
create_directory : Nothing
|
||||
create_directory self = @Builtin_Method "File.create_directory"
|
||||
create_directory self =
|
||||
if Context.Output.is_enabled.not then Error.throw (Forbidden_Operation.Error "Directory creation is forbidden as the Output context is disabled") else
|
||||
self.create_directory_builtin
|
||||
|
||||
|
||||
## PRIVATE
|
||||
Creates the directory represented by this file if it did not exist.
|
||||
create_directory_builtin : Nothing
|
||||
create_directory_builtin self = @Builtin_Method "File.create_directory_builtin"
|
||||
|
||||
## Checks whether the file exists and is a regular file.
|
||||
|
||||
@ -491,7 +546,8 @@ type File
|
||||
file.delete
|
||||
delete : Nothing ! File_Error
|
||||
delete self =
|
||||
File_Error.handle_java_exceptions self self.delete_builtin
|
||||
if Context.Output.is_enabled.not then Error.throw (Forbidden_Operation.Error "File deleting is forbidden as the Output context is disabled") else
|
||||
File_Error.handle_java_exceptions self self.delete_builtin
|
||||
|
||||
## Moves the file to the specified destination.
|
||||
|
||||
@ -501,11 +557,12 @@ type File
|
||||
destination file already exists. Defaults to `False`.
|
||||
copy_to : File -> Boolean -> Nothing ! File_Error
|
||||
copy_to self destination replace_existing=False =
|
||||
File_Error.handle_java_exceptions self <| case replace_existing of
|
||||
True ->
|
||||
copy_options = [StandardCopyOption.REPLACE_EXISTING].to_array
|
||||
self.copy_builtin destination copy_options
|
||||
False -> self.copy_builtin destination Array.empty
|
||||
if Context.Output.is_enabled.not then Error.throw (Forbidden_Operation.Error "File copying is forbidden as the Output context is disabled") else
|
||||
File_Error.handle_java_exceptions self <| case replace_existing of
|
||||
True ->
|
||||
copy_options = [StandardCopyOption.REPLACE_EXISTING].to_array
|
||||
self.copy_builtin destination copy_options
|
||||
False -> self.copy_builtin destination Array.empty
|
||||
|
||||
## Moves the file to the specified destination.
|
||||
|
||||
@ -515,11 +572,12 @@ type File
|
||||
destination file already exists. Defaults to `False`.
|
||||
move_to : File -> Boolean -> Nothing ! File_Error
|
||||
move_to self destination replace_existing=False =
|
||||
File_Error.handle_java_exceptions self <| case replace_existing of
|
||||
True ->
|
||||
copy_options = [StandardCopyOption.REPLACE_EXISTING].to_array
|
||||
self.move_builtin destination copy_options
|
||||
False -> self.move_builtin destination Array.empty
|
||||
if Context.Output.is_enabled.not then Error.throw (Forbidden_Operation.Error "File moving is forbidden as the Output context is disabled") else
|
||||
File_Error.handle_java_exceptions self <| case replace_existing of
|
||||
True ->
|
||||
copy_options = [StandardCopyOption.REPLACE_EXISTING].to_array
|
||||
self.move_builtin destination copy_options
|
||||
False -> self.move_builtin destination Array.empty
|
||||
|
||||
## Deletes the file if it exists on disk.
|
||||
|
||||
@ -553,35 +611,6 @@ type File
|
||||
resource = Managed_Resource.register stream close_stream
|
||||
Input_Stream.Value self resource
|
||||
|
||||
## PRIVATE
|
||||
ADVANCED
|
||||
Returns a new output stream for this file.
|
||||
|
||||
Arguments:
|
||||
- open_options: A vector of `File_Access` objects determining how to open
|
||||
the stream. These options set the access properties of the stream.
|
||||
|
||||
The returned stream should be closed as soon as it is not used anymore.
|
||||
The `with_output_stream` method should be preferred whenever possible.
|
||||
new_output_stream : Vector File_Access -> Output_Stream ! File_Error
|
||||
new_output_stream self open_options =
|
||||
opts = open_options . map (_.to_java) . to_array
|
||||
stream = File_Error.handle_java_exceptions self <|
|
||||
self.output_stream opts
|
||||
## We re-wrap the File Not Found error to return the parent directory
|
||||
instead of the file itself - because the file that is being written
|
||||
may not exist and it will not be an error, it is the parent directory
|
||||
that does not exist is what prevents the write operation from
|
||||
succeeding.
|
||||
## Until #5792 properly fixes catch, we cannot catch
|
||||
`File_Error.Not_Found` specifically, so instead we catch all
|
||||
`File_Error`s and match the needed one.
|
||||
stream_2 = stream.catch File_Error error-> case error of
|
||||
File_Error.Not_Found file_path -> Error.throw (File_Error.Not_Found file_path.parent)
|
||||
_ -> stream
|
||||
resource = Managed_Resource.register stream_2 close_stream
|
||||
Output_Stream.Value self resource
|
||||
|
||||
## PRIVATE
|
||||
Reads last `n` bytes from the file (or less if the file is too small) and
|
||||
returns a vector of bytes.
|
||||
@ -711,9 +740,9 @@ type Output_Stream
|
||||
|
||||
example_write_bytes =
|
||||
file = Examples.scratch_file
|
||||
out_stream = file.new_output_stream [File_Access.Create, File_Access.Write]
|
||||
out_stream.write_bytes "hello".utf_8
|
||||
out_stream.close
|
||||
file.with_output_stream [File_Access.Create, File_Access.Write] out_stream->
|
||||
out_stream.write_bytes "hello".utf_8
|
||||
out_stream.close
|
||||
write_bytes : Vector File_Access -> Nothing ! File_Error
|
||||
write_bytes self contents = self.stream_resource . with java_stream->
|
||||
File_Error.handle_java_exceptions self.file <|
|
||||
@ -737,8 +766,8 @@ type Output_Stream
|
||||
|
||||
example_write_bytes =
|
||||
file = Examples.scratch_file
|
||||
out_stream = file.new_output_stream [File_Access.Create]
|
||||
out_stream.close
|
||||
file.with_output_stream [File_Access.Create] out_stream->
|
||||
out_stream.close
|
||||
close : Nothing
|
||||
close self = self.stream_resource . finalize
|
||||
|
||||
|
@ -2,17 +2,21 @@ import project.Data.Text.Text
|
||||
import project.Data.Text.Encoding.Encoding
|
||||
import project.Data.Text.Extensions
|
||||
import project.Data.Vector.Vector
|
||||
import project.Errors.Common.Unsupported_Argument_Types
|
||||
import project.Error.Error
|
||||
import project.Errors.Common.Dry_Run_Operation
|
||||
import project.Errors.Common.Unsupported_Argument_Types
|
||||
import project.Errors.Encoding_Error.Encoding_Error
|
||||
import project.Errors.File_Error.File_Error
|
||||
import project.Errors.Illegal_Argument.Illegal_Argument
|
||||
import project.Errors.Problem_Behavior.Problem_Behavior
|
||||
import project.Nothing.Nothing
|
||||
import project.Panic.Panic
|
||||
import project.Runtime.Context
|
||||
import project.System.File.Existing_File_Behavior.Existing_File_Behavior
|
||||
import project.System.File.File
|
||||
import project.Warning.Warning
|
||||
|
||||
from project.Data.Boolean import Boolean, True, False
|
||||
|
||||
polyglot java import org.enso.base.Array_Builder
|
||||
|
||||
@ -37,14 +41,39 @@ polyglot java import org.enso.base.Array_Builder
|
||||
Otherwise, the file is created with the encoded text written to it.
|
||||
|
||||
The method returns a `File` object for the written file.
|
||||
|
||||
? Dry Run
|
||||
|
||||
If writing to Output context is not enabled (such as in "Design" mode),
|
||||
then this function will write to a temporary file. This temporary file will
|
||||
be automatically deleted on exit of the Enso process.
|
||||
|
||||
This allows for building the workflow without affecting the real files.
|
||||
@encoding Encoding.default_widget
|
||||
Text.write : (File|Text) -> Encoding -> Existing_File_Behavior -> Problem_Behavior -> File ! Encoding_Error | Illegal_Argument | File_Error
|
||||
Text.write self path encoding=Encoding.utf_8 on_existing_file=Existing_File_Behavior.Backup on_problems=Problem_Behavior.Report_Warning =
|
||||
bytes = self.bytes encoding on_problems
|
||||
file = File.new path
|
||||
r = on_existing_file.write file stream->
|
||||
bytes.if_not_error <|
|
||||
stream.write_bytes bytes
|
||||
r.if_not_error file
|
||||
|
||||
actual = File.new path
|
||||
|
||||
is_enabled = Context.Output.is_enabled
|
||||
|
||||
effective_existing_behaviour = if is_enabled then on_existing_file else
|
||||
case on_existing_file of
|
||||
Existing_File_Behavior.Backup -> Existing_File_Behavior.Overwrite
|
||||
Existing_File_Behavior.Error -> if actual.exists then Error.throw (File_Error.Already_Exists actual) else Existing_File_Behavior.Overwrite
|
||||
_ -> on_existing_file
|
||||
|
||||
file = if is_enabled then actual else actual.create_dry_run_file copy_original=on_existing_file==Existing_File_Behavior.Append
|
||||
|
||||
Context.Output.with_enabled <|
|
||||
r = effective_existing_behaviour.write file stream->
|
||||
bytes.if_not_error <|
|
||||
stream.write_bytes bytes
|
||||
r.if_not_error <|
|
||||
if is_enabled then file else
|
||||
warning = Dry_Run_Operation.Warning "Only a dry run has occurred, with data written to a temporary file."
|
||||
Warning.attach warning file
|
||||
|
||||
## Writes (or appends) the Vector of bytes into the specified file. The behavior
|
||||
specified in the `existing_file` parameter will be used if the file exists.
|
||||
|
@ -9,6 +9,7 @@ import project.Errors.File_Error.File_Error
|
||||
import project.Errors.Problem_Behavior.Problem_Behavior
|
||||
import project.Errors.Unimplemented.Unimplemented
|
||||
import project.Function.Function
|
||||
import project.Meta
|
||||
import project.Network.HTTP.Response.Response
|
||||
import project.Network.URI.URI
|
||||
import project.Nothing.Nothing
|
||||
@ -17,6 +18,10 @@ import project.System.File.File
|
||||
from project.Data.Boolean import Boolean, True, False
|
||||
from project.Data.Json import Invalid_JSON
|
||||
|
||||
from project.Metadata.Widget import Single_Choice
|
||||
from project.Metadata.Choice import Option
|
||||
import project.Metadata.Display
|
||||
|
||||
polyglot java import org.enso.base.file_format.FileFormatSPI
|
||||
|
||||
## PRIVATE
|
||||
@ -35,6 +40,21 @@ get_format callback =
|
||||
@Tail_Call reader (idx + 1)
|
||||
reader 0
|
||||
|
||||
## PRIVATE
|
||||
format_widget : Single_Choice
|
||||
format_widget =
|
||||
all_types = [Auto_Detect] + format_types
|
||||
make_ctor type_obj =
|
||||
type_name = Meta.get_qualified_type_name type_obj
|
||||
|
||||
## Temporary work around to work out if need to add the constructor name
|
||||
is_singleton_type = type_obj==JSON_Format || (type_name.ends_with "_Format" . not)
|
||||
if is_singleton_type then type_name else
|
||||
simple_name = Meta.get_simple_type_name type_obj
|
||||
"(" + type_name + "." + (simple_name.replace "_Format" "") + ")"
|
||||
make_name type_obj = type_obj.to_text.replace "_Format" "" . replace "_" " "
|
||||
Single_Choice display=Display.Always values=(all_types.map n->(Option (make_name n) (make_ctor n)))
|
||||
|
||||
type Auto_Detect
|
||||
## PRIVATE
|
||||
Implements the `File.read` for this `File_Format`
|
||||
@ -127,23 +147,23 @@ type Bytes
|
||||
read self file _ =
|
||||
file.read_bytes
|
||||
|
||||
type JSON_File
|
||||
type JSON_Format
|
||||
## PRIVATE
|
||||
If the File_Format supports reading from the file, return a configured instance.
|
||||
for_file : File -> JSON_File | Nothing
|
||||
for_file : File -> JSON_Format | Nothing
|
||||
for_file file =
|
||||
case file.extension of
|
||||
".json" -> JSON_File
|
||||
".geojson" -> JSON_File
|
||||
".json" -> JSON_Format
|
||||
".geojson" -> JSON_Format
|
||||
_ -> Nothing
|
||||
|
||||
## PRIVATE
|
||||
If the File_Format supports reading from the web response, return a configured instance.
|
||||
for_web : Text -> URI -> JSON_File | Nothing
|
||||
for_web : Text -> URI -> JSON_Format | Nothing
|
||||
for_web content_type _ =
|
||||
first = content_type.split ';' . first . trim
|
||||
case first of
|
||||
"application/json" -> JSON_File
|
||||
"application/json" -> JSON_Format
|
||||
_ -> Nothing
|
||||
|
||||
## PRIVATE
|
||||
|
@ -4,6 +4,7 @@ import Standard.Base.Data.Text.Regex.Match.Match
|
||||
import Standard.Base.Errors.Common.No_Such_Method
|
||||
import Standard.Base.Network.HTTP.Response.Response
|
||||
import Standard.Base.Network.HTTP.Response_Body.Response_Body
|
||||
import Standard.Base.Runtime.Context
|
||||
|
||||
from Standard.Table import Table, Column
|
||||
|
||||
@ -40,7 +41,7 @@ xls =
|
||||
url = "https://enso-data-samples.s3.us-west-1.amazonaws.com/spreadsheet.xls"
|
||||
file = enso_project.data / 'spreadsheet.xls'
|
||||
if file.exists.not then
|
||||
HTTP.fetch url . to_file file
|
||||
Context.Output.with_enabled <| HTTP.fetch url . to_file file
|
||||
file
|
||||
|
||||
## An example XLSX file for experimenting with Table and its APIs.
|
||||
@ -55,14 +56,15 @@ xlsx =
|
||||
url = "https://enso-data-samples.s3.us-west-1.amazonaws.com/spreadsheet.xlsx"
|
||||
file = enso_project.data / 'spreadsheet.xlsx'
|
||||
if file.exists.not then
|
||||
HTTP.fetch url . to_file file
|
||||
Context.Output.with_enabled <| HTTP.fetch url . to_file file
|
||||
file
|
||||
|
||||
## A file that is used for writing temporary data as part of tests.
|
||||
scratch_file : File
|
||||
scratch_file =
|
||||
file = enso_project.data / "scratch_file"
|
||||
if file.exists then file.delete else Nothing
|
||||
if file.exists.not then Nothing else
|
||||
Context.Output.with_enabled <| file.delete
|
||||
file
|
||||
|
||||
## An example duration for experimenting with duration APIs.
|
||||
@ -172,7 +174,7 @@ image_file =
|
||||
url = "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e9/Hue_alpha_falloff.png/320px-Hue_alpha_falloff.png"
|
||||
file = enso_project.data / "image.png"
|
||||
if file.exists.not then
|
||||
HTTP.fetch url . to_file file
|
||||
Context.Output.with_enabled <| HTTP.fetch url . to_file file
|
||||
file
|
||||
|
||||
## A PNG image.
|
||||
|
@ -128,8 +128,8 @@ Text.parse_to_table self pattern="." case_sensitivity=Case_Sensitivity.Sensitive
|
||||
- match_columns: How to match columns between the table and the file.
|
||||
Not used for JSON.
|
||||
- on_problems: What to do if there are problems reading the file.
|
||||
JSON_File.write_table : File -> Table -> Existing_File_Behavior -> Match_Columns -> Problem_Behavior -> File
|
||||
JSON_File.write_table self file table on_existing_file match_columns on_problems =
|
||||
JSON_Format.write_table : File -> Table -> Existing_File_Behavior -> Match_Columns -> Problem_Behavior -> File
|
||||
JSON_Format.write_table self file table on_existing_file match_columns on_problems =
|
||||
_ = [match_columns, on_problems]
|
||||
if file.exists.not then table.to_json.write file else
|
||||
case on_existing_file of
|
||||
|
@ -1,4 +1,5 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Runtime.Context
|
||||
|
||||
import project.Suite_Config.Suite_Config
|
||||
import project.Test.Test
|
||||
@ -18,8 +19,10 @@ wrap_junit_testsuites config builder ~action =
|
||||
|
||||
if config.should_output_junit then
|
||||
builder.append '</testsuites>\n'
|
||||
config.output_path.parent.create_directory
|
||||
builder.toString.write config.output_path
|
||||
|
||||
Context.Output.with_enabled <|
|
||||
config.output_path.parent.create_directory
|
||||
builder.toString.write config.output_path
|
||||
|
||||
result
|
||||
|
||||
|
@ -11,7 +11,7 @@ import org.enso.interpreter.runtime.state.State;
|
||||
|
||||
@BuiltinMethod(
|
||||
type = "Context",
|
||||
name = "is_enabled",
|
||||
name = "is_enabled_builtin",
|
||||
description = "Check if the context is enabled in the provided execution environment.")
|
||||
public class ContextIsEnabledNode extends Node {
|
||||
private @Child ExpectStringNode expectStringNode = ExpectStringNode.build();
|
||||
|
@ -42,7 +42,7 @@ public final class EnsoFile implements TruffleObject {
|
||||
this.truffleFile = truffleFile;
|
||||
}
|
||||
|
||||
@Builtin.Method
|
||||
@Builtin.Method(name = "output_stream_builtin")
|
||||
@Builtin.WrapException(from = IOException.class)
|
||||
@Builtin.ReturningGuestObject
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
@ -155,7 +155,7 @@ public final class EnsoFile implements TruffleObject {
|
||||
return this.truffleFile.isDirectory();
|
||||
}
|
||||
|
||||
@Builtin.Method(name = "create_directory")
|
||||
@Builtin.Method(name = "create_directory_builtin")
|
||||
@CompilerDirectives.TruffleBoundary
|
||||
public void createDirectories() {
|
||||
try {
|
||||
|
@ -0,0 +1,42 @@
|
||||
package org.enso.base;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class DryRunFileManager {
|
||||
static final Map<String, String> files = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Creates a temporary file for the given path. If the path is already a dry run temporary file,
|
||||
* the same path will be returned.
|
||||
*
|
||||
* @param path the path to the file to make a temporary file of.
|
||||
* @return the path to the temporary file.
|
||||
*/
|
||||
public static String getTemporaryFile(String path) {
|
||||
return files.computeIfAbsent(
|
||||
path,
|
||||
k -> {
|
||||
if (files.containsValue(k)) {
|
||||
// Existing temporary file so return this.
|
||||
return k;
|
||||
}
|
||||
|
||||
var filename = new File(k).getName();
|
||||
var lastDot = filename.lastIndexOf('.');
|
||||
var prefix = lastDot == -1 ? filename : filename.substring(0, lastDot);
|
||||
prefix = prefix + "_ensodryrun";
|
||||
var extension = lastDot == -1 ? "" : filename.substring(lastDot);
|
||||
|
||||
try {
|
||||
var temp = File.createTempFile(prefix, extension);
|
||||
temp.deleteOnExit();
|
||||
return temp.getAbsolutePath();
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -9,6 +9,6 @@ public class JSONFormatSPI extends FileFormatSPI {
|
||||
|
||||
@Override
|
||||
protected String getTypeName() {
|
||||
return "JSON_File";
|
||||
return "JSON_Format";
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Runtime.Ref.Ref
|
||||
import Standard.Base.Runtime.Context
|
||||
|
||||
import Standard.Table.Data.Type.Value_Type.Bits
|
||||
from Standard.Table import Table, Value_Type
|
||||
@ -154,11 +155,11 @@ sqlite_spec connection prefix =
|
||||
spec =
|
||||
enso_project.data.create_directory
|
||||
file = enso_project.data / "sqlite_test.db"
|
||||
file.delete_if_exists
|
||||
Context.Output.with_enabled <| file.delete_if_exists
|
||||
in_file_prefix = "[SQLite File] "
|
||||
sqlite_spec (Database.connect (SQLite file)) in_file_prefix
|
||||
Upload_Spec.spec (_ -> Database.connect (SQLite file)) in_file_prefix
|
||||
file.delete
|
||||
Context.Output.with_enabled <| file.delete
|
||||
|
||||
in_memory_prefix = "[SQLite In-Memory] "
|
||||
sqlite_spec (Database.connect (SQLite In_Memory)) in_memory_prefix
|
||||
@ -166,7 +167,7 @@ spec =
|
||||
|
||||
SQLite_Type_Mapping_Spec.spec
|
||||
|
||||
Test.group "SQLite_Format should allow connecting to SQLite files" <|
|
||||
Test.group "SQLite_Format should allow connecting to SQLite files" <| Context.Output.with_enabled <|
|
||||
file.delete_if_exists
|
||||
|
||||
connection = Database.connect (SQLite file)
|
||||
|
@ -1,4 +1,5 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Runtime.Context
|
||||
|
||||
from Standard.Table import Table, Column, Delimited
|
||||
import Standard.Table.Main as Table_Module
|
||||
@ -91,7 +92,7 @@ spec =
|
||||
res.should_equal expected
|
||||
|
||||
|
||||
Test.specify 'should write CSV to a file' <|
|
||||
Test.specify 'should write CSV to a file' <| Context.Output.with_enabled <|
|
||||
varied_column = (enso_project.data / "varied_column.csv") . read
|
||||
out = enso_project.data / "transient" / "out.csv"
|
||||
out.delete_if_exists
|
||||
@ -109,7 +110,7 @@ spec =
|
||||
out.read_text.should_equal exp
|
||||
out.delete_if_exists
|
||||
|
||||
Test.group "Integration" <|
|
||||
Test.group "Integration" <| Context.Output.with_enabled <|
|
||||
Test.specify "should be able to round-trip a table with all kinds of weird characters to CSV and back" <|
|
||||
names = ['Śłąęźż");DROP TABLE Students;--', 'This;Name;;Is""Strange', 'Marcin,,', '\'', 'a\n\nb', 'a\tc', Nothing, Nothing, Nothing, '42', '💁👌🎍😍', '', 'null?\0?', 'FFFD', '\uFFFD', '\r\n', 'a\r\nb\n\rc\rd\ne', 'what about these # ?? // /* hmm */ is it included?', 'and the rare \v vertical tab?']
|
||||
d = Date_Time.new 2015 10 29 23 55 49
|
||||
|
@ -2,6 +2,7 @@ from Standard.Base import all
|
||||
import Standard.Base.Errors.Encoding_Error.Encoding_Error
|
||||
import Standard.Base.Errors.File_Error.File_Error
|
||||
import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
|
||||
import Standard.Base.Runtime.Context
|
||||
|
||||
from Standard.Table import Table, Column, Data_Formatter, Quote_Style, Delimited
|
||||
import Standard.Table.Data.Table_Conversions
|
||||
@ -102,7 +103,7 @@ spec =
|
||||
r2.should_fail_with File_Error
|
||||
r2.catch.should_be_a File_Error.IO_Error
|
||||
|
||||
Test.specify "should work with all kinds of line endings" <|
|
||||
Test.specify "should work with all kinds of line endings" <| Context.Output.with_enabled <|
|
||||
path name = enso_project.data / 'transient' / name
|
||||
create_file name ending_style =
|
||||
lines = ['a,b,c', 'd,e,f', '1,2,3']
|
||||
@ -129,7 +130,7 @@ spec =
|
||||
|
||||
['crlf.csv', 'lf.csv', 'cr.csv', 'mixed.csv'].each (path >> .delete)
|
||||
|
||||
Test.specify "should allow to override line endings style" <|
|
||||
Test.specify "should allow to override line endings style" <| Context.Output.with_enabled <|
|
||||
file = enso_project.data / "transient" / "lf.csv"
|
||||
lines = ['a,b,c', 'd,e,f', '1,2,3']
|
||||
text = lines.join '\n'
|
||||
@ -170,7 +171,7 @@ spec =
|
||||
table.at '🚀b' . to_vector . should_equal ['✨🚀🚧😍😃😍😎😙😉☺']
|
||||
table.at 'ć😎' . to_vector . should_equal ['แมวมีสี่ขา']
|
||||
|
||||
Test.specify "should report errors when encountering malformed characters" <|
|
||||
Test.specify "should report errors when encountering malformed characters" <| Context.Output.with_enabled <|
|
||||
utf8_file = (enso_project.data / "transient" / "utf8_invalid.csv")
|
||||
utf8_bytes = [97, 44, 98, 44, 99, 10, -60, -123, 44, -17, -65, -65, 44, -61, 40, -61, 40, 10]
|
||||
utf8_bytes.write_bytes utf8_file
|
||||
|
@ -2,6 +2,7 @@ from Standard.Base import all
|
||||
import Standard.Base.Errors.Encoding_Error.Encoding_Error
|
||||
import Standard.Base.Errors.File_Error.File_Error
|
||||
import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
|
||||
import Standard.Base.Runtime.Context
|
||||
|
||||
from Standard.Table import Table, Column, Data_Formatter, Quote_Style, Match_Columns, Delimited
|
||||
from Standard.Table.Errors import all
|
||||
@ -24,7 +25,7 @@ join_lines lines trailing_newline=True =
|
||||
|
||||
spec =
|
||||
line_ending_pairs = [[Line_Ending_Style.Unix, '\n'], [Line_Ending_Style.Windows, '\r\n'], [Line_Ending_Style.Mac_Legacy, '\r']]
|
||||
Test.group "Delimited File Writing" <|
|
||||
Test.group "Delimited File Writing" <| Context.Output.with_enabled <|
|
||||
Test.specify "should correctly write a simple table and return the written file object on success" <|
|
||||
table = Table.new [["A", [1,2,3]], ["B", [1.0,1.5,2.2]], ["C", ["x","y","z"]], ["D", ["a", 2, My_Type.Value 10]]]
|
||||
file = (enso_project.data / "transient" / "written.csv")
|
||||
|
@ -1,6 +1,7 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Errors.File_Error.File_Error
|
||||
import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
|
||||
import Standard.Base.Runtime.Context
|
||||
|
||||
from Standard.Table import Table, Match_Columns, Excel, Excel_Range, Data_Formatter, Sheet_Names, Range_Names, Worksheet, Cell_Range, Delimited, Excel_Workbook
|
||||
|
||||
@ -67,7 +68,7 @@ spec_fmt header file read_method sheet_count=5 =
|
||||
t_3.at 'C' . to_vector . should_equal [43.2, 54]
|
||||
|
||||
spec_write suffix test_sheet_name =
|
||||
Test.group ("Write " + suffix + " Files") <|
|
||||
Test.group ("Write " + suffix + " Files") <| Context.Output.with_enabled <|
|
||||
out = enso_project.data / ('out.' + suffix)
|
||||
out_bak = enso_project.data / ('out.' + suffix + '.bak')
|
||||
table = enso_project.data/'varied_column.csv' . read
|
||||
@ -678,7 +679,7 @@ spec =
|
||||
r2.should_fail_with File_Error
|
||||
r2.catch.should_be_a File_Error.Corrupted_Format
|
||||
|
||||
Test.specify "should handle malformed XLS files gracefully" <|
|
||||
Test.specify "should handle malformed XLS files gracefully" <| Context.Output.with_enabled <|
|
||||
bad_file = enso_project.data / "transient" / "malformed.xls"
|
||||
"not really an XLS file contents...".write bad_file on_existing_file=Existing_File_Behavior.Overwrite
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Errors.File_Error.File_Error
|
||||
import Standard.Base.Runtime.Context
|
||||
|
||||
from Standard.Table import all
|
||||
import Standard.Table.Errors.Invalid_JSON_Format
|
||||
@ -10,7 +11,7 @@ import Standard.Test.Extensions
|
||||
import project.Util
|
||||
|
||||
|
||||
spec = Test.group 'Various File Format support on Table' <|
|
||||
spec = Test.group 'Various File Format support on Table' <| Context.Output.with_enabled <|
|
||||
t1 = Table.new [["X", [1, 2, 3]]]
|
||||
transient = enso_project.data / "transient"
|
||||
simple_empty = enso_project.data/'simple_empty.csv' . read
|
||||
|
@ -53,7 +53,7 @@ spec =
|
||||
Problems.expect_only_warning Encoding_Error <|
|
||||
windows_log.read (Plain_Text Encoding.ascii)
|
||||
|
||||
Test.group "JSON_File" <|
|
||||
Test.group "JSON_Format" <|
|
||||
Test.specify "should be able to read a file as Json" <|
|
||||
f1 = enso_project.data / "sample.json"
|
||||
j1 = f1.read
|
||||
@ -62,7 +62,7 @@ spec =
|
||||
j1.at "not" . should_equal Nothing
|
||||
|
||||
f2 = enso_project.data / "sample-json.weird-extension"
|
||||
j2 = f2.read JSON_File
|
||||
j2 = f2.read JSON_Format
|
||||
j2.at 0 . at "foo" . should_equal "bar"
|
||||
j2.at 1 . should_equal 42
|
||||
j2.at 2 . should_equal Nothing
|
||||
|
@ -3,6 +3,7 @@ import Standard.Base.Errors.Encoding_Error.Encoding_Error
|
||||
import Standard.Base.Errors.File_Error.File_Error
|
||||
import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
|
||||
import Standard.Base.Errors.Illegal_State.Illegal_State
|
||||
import Standard.Base.Runtime.Context
|
||||
|
||||
polyglot java import org.enso.base_test_helpers.FileSystemHelper
|
||||
|
||||
@ -18,7 +19,7 @@ spec =
|
||||
windows_file = enso_project.data / "windows.txt"
|
||||
non_existent_file = File.new "does_not_exist.txt"
|
||||
|
||||
Test.group "File Operations" <|
|
||||
Test.group "File Operations" <| Context.Output.with_enabled <|
|
||||
Test.specify "should allow creating a new file" <|
|
||||
path = sample_file.path
|
||||
File.new path
|
||||
@ -132,13 +133,14 @@ spec =
|
||||
Test.specify "should allow to read last n bytes from a file" <|
|
||||
file = enso_project.data / "transient" / "bytes.txt"
|
||||
data = [1, 0, 0, 1, 2, 100, 20]
|
||||
data.write_bytes file
|
||||
file.read_last_bytes 0 . should_equal []
|
||||
file.read_last_bytes 1 . should_equal [20]
|
||||
file.read_last_bytes 2 . should_equal [100, 20]
|
||||
file.read_last_bytes 5 . should_equal [0, 1, 2, 100, 20]
|
||||
file.read_last_bytes 1000 . should_equal data
|
||||
file.delete
|
||||
Context.Output.with_enabled <|
|
||||
data.write_bytes file
|
||||
file.read_last_bytes 0 . should_equal []
|
||||
file.read_last_bytes 1 . should_equal [20]
|
||||
file.read_last_bytes 2 . should_equal [100, 20]
|
||||
file.read_last_bytes 5 . should_equal [0, 1, 2, 100, 20]
|
||||
file.read_last_bytes 1000 . should_equal data
|
||||
file.delete
|
||||
|
||||
Test.specify "should handle exceptions when reading a non-existent file" <|
|
||||
file = File.new "does_not_exist.txt"
|
||||
@ -203,7 +205,7 @@ spec =
|
||||
contents_2 = Data.read_text file
|
||||
contents_2.should_start_with "Cupcake ipsum dolor sit amet."
|
||||
|
||||
Test.group "write operations" <|
|
||||
Test.group "write operations" <| Context.Output.with_enabled <|
|
||||
data = [32, 127, -128, 0]
|
||||
data_2 = [10, 15, 20, 30]
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Errors.Encoding_Error.Encoding_Error
|
||||
import Standard.Base.Runtime.Context
|
||||
|
||||
polyglot java import java.nio.CharBuffer
|
||||
|
||||
@ -24,7 +25,7 @@ spec =
|
||||
f.delete
|
||||
f.exists.should_be_false
|
||||
|
||||
Test.specify "should work correctly when reading chunks of varying sizes" <|
|
||||
Test.specify "should work correctly when reading chunks of varying sizes" <| Context.Output.with_enabled <|
|
||||
f = enso_project.data / "transient" / "varying_chunks.txt"
|
||||
fragment = 'Hello 😎🚀🚧!'
|
||||
contents = 1.up_to 1000 . map _->fragment . join '\n'
|
||||
|
@ -1,6 +1,7 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Errors.Encoding_Error.Encoding_Error
|
||||
import Standard.Base.Errors.Illegal_State.Illegal_State
|
||||
import Standard.Base.Runtime.Context
|
||||
|
||||
polyglot java import org.enso.base.Encoding_Utils
|
||||
polyglot java import java.nio.CharBuffer
|
||||
@ -9,7 +10,7 @@ from Standard.Test import Test, Test_Suite, Problems
|
||||
import Standard.Test.Extensions
|
||||
|
||||
spec =
|
||||
Test.group "ReportingStreamEncoder" <|
|
||||
Test.group "ReportingStreamEncoder" <| Context.Output.with_enabled <|
|
||||
Test.specify "should allow writing a file codepoint by codepoint" <|
|
||||
f = enso_project.data / "transient" / "char-by-char.txt"
|
||||
f.delete_if_exists
|
||||
|
@ -1,4 +1,5 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Runtime.Context
|
||||
|
||||
from Standard.Table import Table, Aggregate_Column, Value_Type
|
||||
|
||||
@ -99,7 +100,7 @@ visualization_spec connection =
|
||||
Visualization.prepare_visualization Value_Type.Char . should_equal (make_json Value_Type.Char)
|
||||
Visualization.prepare_visualization Value_Type.Unsupported_Data_Type . should_equal (make_json Value_Type.Unsupported_Data_Type)
|
||||
|
||||
spec =
|
||||
spec = Context.Output.with_enabled <|
|
||||
enso_project.data.create_directory
|
||||
file = enso_project.data / "sqlite_test.db"
|
||||
file.delete_if_exists
|
||||
|
@ -23,7 +23,12 @@ type Context
|
||||
if self.is_enabled environment then action else Panic.throw (Forbidden_Operation.Error self.name)
|
||||
|
||||
is_enabled : Text -> Boolean
|
||||
is_enabled self environment="design" = @Builtin_Method "Context.is_enabled"
|
||||
is_enabled self environment="design" =
|
||||
self.is_enabled_builtin environment
|
||||
|
||||
## PRIVATE
|
||||
is_enabled_builtin : Text -> Boolean
|
||||
is_enabled_builtin self environment = @Builtin_Method "Context.is_enabled_builtin"
|
||||
|
||||
current_execution_environment : Text
|
||||
current_execution_environment = @Builtin_Method "Runtime.current_execution_environment"
|
||||
|
Loading…
Reference in New Issue
Block a user