is it really possible to use classes and interfaces to mock file system without libraries in crystal ?
It is possible to monkey-patch
Dir for your use-case, but if this is for specs then you might find testing with direct
IO inputs would be easier then mocking the file system. For example, take the following method:
def reverse_contents(file : File) : Nil content = file.gets_to_end.reverse file.rewind << content end
This method doesn’t need to have access to a file directly, it can instead use
IO which allows you to do this:
require "spec" it "reverses contents" do io = IO::Memory.new io << "foo bar baz" io.rewind reverse_contents io io.to_s.should eq "zab rab oof" end
The short answer is yes. Totally possible for you to do something like:
module FileSystemInterface abstract def write(path : String | Path, content : String) : Nil abstract def read(path : String | Path) : String end class LocalFileSystem include FileSystemInterface def write(path : String | Path, content : String) : Nil File.write path, content end def read(path : String | Path) : String File.read path end end class MockFileSystem include FileSystemInterface @files = Hash(String, String).new def write(path : String | Path, content : String) : Nil @files[path.to_s] = content end def read(path : String | Path) : String @files[path.to_s]? || raise "File does not exist" end end
Then your logic can depend upon
FileSystemInterface, defaulting to
LocalFileSystem, but using
MockFileSystem in specs.
this works with file extensions ? i want to obfuscate the file extension i want to make pdf looks like txt but actually it is txt is it possible with classes and interfaces ?
If that’s what you mean by “filesystem mocking” then I’m not sure I follow why you think you need classes and interfaces. If you just want to save a PDF with a
.txt file extension then you can just do that when you save the file.