Skip to content

Commit

Permalink
Continued Execution Context work and some little fixes (#6506)
Browse files Browse the repository at this point in the history
- Add `with_disabled` shortcut for `Context`.
- Protect `Image.write` behind `Context.Output`.
- Correct text on the `Forbidden_Operation` error message.
- Remove context overrides from tests.
- Add `File` operations tests with `Context.Output` disabled.
- Add tests for `Text.write` operations with `Context.Output` disabled.
- Use a better method to make `File_Format` dropdown widget.
- Fix bug in `Invalid_Format.to_display_text`.
  • Loading branch information
jdunkerley authored May 3, 2023
1 parent 6ce0b4d commit bb8f910
Show file tree
Hide file tree
Showing 17 changed files with 274 additions and 41 deletions.
5 changes: 5 additions & 0 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Runtime.enso
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,11 @@ type Context
with_enabled self ~action =
with_enabled_context self Runtime.current_execution_environment action

## PRIVATE
Run an action with the Context disabled.
with_disabled : Function -> Any
with_disabled self ~action =
with_disabled_context self Runtime.current_execution_environment action

## PRIVATE
ADVANCED
Expand Down
13 changes: 7 additions & 6 deletions distribution/lib/Standard/Base/0.0.0-dev/src/System/File.enso
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ type File
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
Context.Output.with_enabled <|
self.copy_to temp replace_existing=True
temp

## ALIAS Current Directory
Expand Down Expand Up @@ -160,7 +161,7 @@ type File
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
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
Expand Down Expand Up @@ -414,7 +415,7 @@ type File
(Examples.data_dir / "my_directory") . create_directory
create_directory : Nothing
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
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


Expand Down Expand Up @@ -546,7 +547,7 @@ type File
file.delete
delete : Nothing ! File_Error
delete self =
if Context.Output.is_enabled.not then Error.throw (Forbidden_Operation.Error "File deleting is forbidden as the Output context is disabled") else
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.
Expand All @@ -557,7 +558,7 @@ type File
destination file already exists. Defaults to `False`.
copy_to : File -> Boolean -> Nothing ! File_Error
copy_to self destination replace_existing=False =
if Context.Output.is_enabled.not then Error.throw (Forbidden_Operation.Error "File copying is forbidden as the Output context is disabled") else
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
Expand All @@ -572,7 +573,7 @@ type File
destination file already exists. Defaults to `False`.
move_to : File -> Boolean -> Nothing ! File_Error
move_to self destination replace_existing=False =
if Context.Output.is_enabled.not then Error.throw (Forbidden_Operation.Error "File moving is forbidden as the Output context is disabled") else
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,10 @@ 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)
ctors = Meta.meta type_obj . constructors
is_singleton_type = ctors.length == 0
if is_singleton_type then type_name else
simple_name = Meta.get_simple_type_name type_obj
"(" + type_name + "." + (simple_name.replace "_Format" "") + ")"
"(" + type_name + "." + ctors.first.name + ")"
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)))

Expand Down
21 changes: 12 additions & 9 deletions distribution/lib/Standard/Image/0.0.0-dev/src/Data/Image.enso
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from Standard.Base import all
import Standard.Base.Runtime.Context
import Standard.Base.Errors.Common.Forbidden_Operation
import Standard.Base.Errors.File_Error.File_Error

from Standard.Base.Data.Ordering import all
Expand Down Expand Up @@ -98,15 +100,16 @@ type Image
image.write path image [Write_Flag.JPEG_Quality 40, Write_Flag.JPEG_Progressive]
write : (Text | File) -> (Write_Flag | Vector) -> Nothing ! File_Error
write self location flags=[] =
path = case location of
_ : File -> location.path
_ -> location
write_flags = case flags of
_ : Vector -> flags
_ -> [flags]
int_flags = MatOfInt.new (write_flags.flat_map x-> [x.to_integer, x.value]).to_array
Panic.catch JException (Java_Codecs.write path self.opencv_mat int_flags) _->
Error.throw (File_Error.IO_Error (File.new path) 'Failed to write to the file')
if Context.Output.is_enabled.not then Error.throw (Forbidden_Operation.Error "Writing the image to a file is forbidden as the Output context is disabled.") else
path = case location of
_ : File -> location.path
_ -> location
write_flags = case flags of
_ : Vector -> flags
_ -> [flags]
int_flags = MatOfInt.new (write_flags.flat_map x-> [x.to_integer, x.value]).to_array
Panic.catch JException (Java_Codecs.write path self.opencv_mat int_flags) _->
Error.throw (File_Error.IO_Error (File.new path) 'Failed to write to the file')

## PRIVATE

Expand Down
2 changes: 1 addition & 1 deletion distribution/lib/Standard/Table/0.0.0-dev/src/Errors.enso
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ type Invalid_Format
Pretty print the invalid format error.
to_display_text : Text
to_display_text self =
self.cells.length+" cells in column "+self.column+" had invalid format for type "+self.value_type.to_text+"."
self.cells.length.to_text+" cells in column "+self.column+" had invalid format for type "+self.value_type.to_text+"."

## Indicates that an empty file was encountered, so no data could be loaded.
type Empty_File_Error
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from Standard.Base import all
import Standard.Base.Errors.Common.Forbidden_Operation
import Standard.Base.Errors.File_Error.File_Error
import Standard.Base.Runtime.Context

from Standard.Image import Image, Read_Flag, Write_Flag
import Standard.Image.Image_File_Format.Image_File_Format
Expand Down Expand Up @@ -27,16 +29,19 @@ spec =
result = Image.read (enso_project.root / 'no_such_file.png')
result . should_fail_with File_Error
result.catch.should_be_a File_Error.IO_Error

Test.specify "should read a color image" <|
img = Image.read rgba_file
img.rows.should_equal 160
img.columns.should_equal 320
img.channels.should_equal 3

Test.specify "should read an image as grayscale" <|
img = Image.read rgba_file Read_Flag.Grayscale
img.rows.should_equal 160
img.columns.should_equal 320
img.channels.should_equal 1

Test.specify "should read an image with an alpha channel" <|
img = Image.read rgba_file Read_Flag.Alpha_Channel
img.rows.should_equal 160
Expand Down Expand Up @@ -74,4 +79,29 @@ spec =
img.columns.should_equal 320
img.channels.should_equal 3

Test.group "Image Write" <|
Test.specify "should write a Bitmap file" <|
img = Image.read rgba_file

out = enso_project.root / "out_alpha.bmp"
img.write out
out.exists.should_be_true

bmp = Image.read out
bmp.rows.should_equal 160
bmp.columns.should_equal 320

out.delete_if_exists

Test.specify "should not write if Context.Output is disabled." <|
img = Image.read rgba_file

out = enso_project.root / "out_alpha.bmp"

Context.Output.with_disabled <|
img.write out . should_fail_with Forbidden_Operation
out.exists.should_be_false

out.delete_if_exists

main = Test_Suite.run_main spec
4 changes: 2 additions & 2 deletions test/Image_Tests/src/Main.enso
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ from Standard.Base import all

from Standard.Test import Test_Suite

import project.Image_Read_Spec
import project.Image_Read_Write_Spec
import project.Data.Image_Spec
import project.Data.Matrix_Spec

main = Test_Suite.run_main <|
Image_Read_Spec.spec
Image_Read_Write_Spec.spec
Matrix_Spec.spec
Image_Spec.spec
6 changes: 3 additions & 3 deletions test/Table_Tests/src/Database/SQLite_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -155,19 +155,19 @@ sqlite_spec connection prefix =
spec =
enso_project.data.create_directory
file = enso_project.data / "sqlite_test.db"
Context.Output.with_enabled <| file.delete_if_exists
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
Context.Output.with_enabled <| file.delete
file.delete

in_memory_prefix = "[SQLite In-Memory] "
sqlite_spec (Database.connect (SQLite In_Memory)) in_memory_prefix
Upload_Spec.spec (_ -> Database.connect (SQLite In_Memory)) in_memory_prefix persistent_connector=False

SQLite_Type_Mapping_Spec.spec

Test.group "SQLite_Format should allow connecting to SQLite files" <| Context.Output.with_enabled <|
Test.group "SQLite_Format should allow connecting to SQLite files" <|
file.delete_if_exists

connection = Database.connect (SQLite file)
Expand Down
4 changes: 2 additions & 2 deletions test/Table_Tests/src/IO/Csv_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ spec =
res.should_equal expected


Test.specify 'should write CSV to a file' <| Context.Output.with_enabled <|
Test.specify 'should write CSV to a file' <|
varied_column = (enso_project.data / "varied_column.csv") . read
out = enso_project.data / "transient" / "out.csv"
out.delete_if_exists
Expand All @@ -110,7 +110,7 @@ spec =
out.read_text.should_equal exp
out.delete_if_exists

Test.group "Integration" <| Context.Output.with_enabled <|
Test.group "Integration" <|
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
Expand Down
6 changes: 3 additions & 3 deletions test/Table_Tests/src/IO/Delimited_Read_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -103,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" <| Context.Output.with_enabled <|
Test.specify "should work with all kinds of line endings" <|
path name = enso_project.data / 'transient' / name
create_file name ending_style =
lines = ['a,b,c', 'd,e,f', '1,2,3']
Expand All @@ -130,7 +130,7 @@ spec =

['crlf.csv', 'lf.csv', 'cr.csv', 'mixed.csv'].each (path >> .delete)

Test.specify "should allow to override line endings style" <| Context.Output.with_enabled <|
Test.specify "should allow to override line endings style" <|
file = enso_project.data / "transient" / "lf.csv"
lines = ['a,b,c', 'd,e,f', '1,2,3']
text = lines.join '\n'
Expand Down Expand Up @@ -171,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" <| Context.Output.with_enabled <|
Test.specify "should report errors when encountering malformed characters" <|
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
Expand Down
2 changes: 1 addition & 1 deletion test/Table_Tests/src/IO/Delimited_Write_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -25,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" <| Context.Output.with_enabled <|
Test.group "Delimited File Writing" <|
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")
Expand Down
4 changes: 2 additions & 2 deletions test/Table_Tests/src/IO/Excel_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -68,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") <| Context.Output.with_enabled <|
Test.group ("Write " + suffix + " Files") <|
out = enso_project.data / ('out.' + suffix)
out_bak = enso_project.data / ('out.' + suffix + '.bak')
table = enso_project.data/'varied_column.csv' . read
Expand Down Expand Up @@ -679,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" <| Context.Output.with_enabled <|
Test.specify "should handle malformed XLS files gracefully" <|
bad_file = enso_project.data / "transient" / "malformed.xls"
"not really an XLS file contents...".write bad_file on_existing_file=Existing_File_Behavior.Overwrite

Expand Down
3 changes: 1 addition & 2 deletions test/Table_Tests/src/IO/Formats_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import Standard.Test.Extensions

import project.Util


spec = Test.group 'Various File Format support on Table' <| Context.Output.with_enabled <|
spec = Test.group 'Various File Format support on Table' <|
t1 = Table.new [["X", [1, 2, 3]]]
transient = enso_project.data / "transient"
simple_empty = enso_project.data/'simple_empty.csv' . read
Expand Down
Loading

0 comments on commit bb8f910

Please sign in to comment.