Skip to content

Commit

Permalink
[stdlib,spec] Add basic specs for File, temporary workaround for `I…
Browse files Browse the repository at this point in the history
…O#gets` issue.

The explicit return in `IO#gets` caused issues with the value of `self` (see myst-lang#155), so `raise/rescue` is used as a temporary workaround.

Also, the specs for File are a bit light, because there currently isn't a great way of mocking FileDescriptor input, nor accessing the Interpreter's `fd_pool` to check for opening/closing of files.
  • Loading branch information
faultyserver committed Feb 13, 2018
1 parent d2b83bc commit fb447f8
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 3 deletions.
28 changes: 28 additions & 0 deletions spec/myst/file_spec.mt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
require "stdlib/spec.mt"


describe("File#open") do
it("returns a new File instance for the given file") do
file = File.open("spec/support/misc/fixed_size_file.txt", "r")

assert(file.type.to_s == "File")
end

it("defaults to 'read' mode if no mode is given") do
file = File.open("spec/support/misc/fixed_size_file.txt")
assert(file.mode == "r")
end
end

describe("File#close") do
# TODO: test that the file descriptor is properly closed.
end

describe("File#size") do
it("returns an Integer of the number of bytes the file contains") do
# `fixed_size_file.txt` should always be 63 bytes in size.
file = %File{"spec/support/misc/fixed_size_file.txt", "r"}

assert(file.size == 63)
end
end
1 change: 1 addition & 0 deletions spec/myst/spec.mt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ include Spec.DSL
# files under this directory.
require "./boolean_spec.mt"
require "./enumerable_spec.mt"
require "./file_spec.mt"
require "./float_spec.mt"
require "./integer_spec.mt"
require "./io_spec.mt"
Expand Down
1 change: 1 addition & 0 deletions spec/support/misc/fixed_size_file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This file has a fixed size of 63 bytes. Do not edit this file!
12 changes: 10 additions & 2 deletions src/myst/interpreter/native_lib/file.cr
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,33 @@ module Myst
file = File.open(name.value, mode.value)
@fd_pool[file.fd] = file

this.ivars["fd"] = TInteger.new(file.fd.to_i64)
this.ivars["@fd"] = TInteger.new(file.fd.to_i64)
this.ivars["@mode"] = mode
this
end

NativeLib.method :file_close, TInstance do
fd = this.ivars["fd"].as(TInteger)
fd = this.ivars["@fd"].as(TInteger)
file = @fd_pool[fd.value]
file.close
@fd_pool.delete(fd.value)
TNil.new
end

NativeLib.method :file_size, TInstance do
fd = this.ivars["@fd"].as(TInteger)
file = @fd_pool[fd.value].as(File)
TInteger.new(file.size.to_i64)
end


def init_file(kernel : TModule, fd_type : TType)
file_type = TType.new("File", kernel.scope, fd_type)
kernel.scope["File"] = file_type

NativeLib.def_instance_method(file_type, :initialize, :file_init)
NativeLib.def_instance_method(file_type, :close, :file_close)
NativeLib.def_instance_method(file_type, :size, :file_size)
file_type
end
end
Expand Down
2 changes: 2 additions & 0 deletions stdlib/file.mt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ deftype File
defstatic open(name : String, mode)
%File{name, mode}
end

def mode; @mode; end
end
8 changes: 7 additions & 1 deletion stdlib/io.mt
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,20 @@ deftype IO
def gets
buffer = ""
last_char = ""

while last_char != "\n"
buffer += last_char
last_char = read(1)

when last_char == "" || last_char == "\0"
return buffer
# raise/rescue is a work around for the currently-broken explicit
# returns, mentioned in https://github.com/myst-lang/myst/issues/155.
raise buffer
end
end

buffer
rescue buffer
buffer
end
end

0 comments on commit fb447f8

Please sign in to comment.