howl.util.SandboxedLoader

local loader, dir

before_each ->
  dir = File.tmpdir!
  loader = SandboxedLoader dir, 'foo', {}

after_each -> dir\rm_r!

returns a Sandbox

assert.equals 'Sandbox', typeof loader

(exposed sandbox helpers)

<name>_file(rel_path)

returns a File object for the given file

assert.equals dir\join('file.lua'), loader -> foo_file 'file.lua'

<name>_load(rel_basename)

loads relative bytecode, lua and moonscript files

dir\join('aux_lua.lua').contents = '_G.loaded_lua = true'
dir\join('aux_moon.moon').contents = '_G.loaded_moon = true'
dir\join('aux_bc.bc').contents = string.dump loadstring('_G.loaded_bc = true'), false
loader ->
  foo_load 'aux_lua'
  foo_load 'aux_moon'
  foo_load 'aux_bc'

assert.is_true _G.loaded_lua
assert.is_true _G.loaded_moon
assert.is_true _G.loaded_bc

prefers bytecode to Lua to Moonscript

dir\join('one.bc').contents = string.dump loadstring('return "bytecode"'), false
dir\join('one.lua').contents = 'return "lua"'

dir\join('two.lua').contents = 'return "lua"'
dir\join('two.moon').contents = 'return "moon"'

assert.equal 'bytecode', loader -> foo_load 'one'
assert.equal 'lua', loader -> foo_load 'two'

only loads each file once

dir\join('aux.lua').contents = [[
  _G.load_count = _G.load_count or 0
  _G.load_count = _G.load_count + 1
  return _G.load_count
]]
assert.equals 1, loader -> foo_load 'aux'
assert.equals 1, loader -> foo_load 'aux'

signals an error upon cyclic dependencies

dir\join('aux.lua').contents = 'foo_load("aux2")'
dir\join('aux2.lua').contents = 'foo_load("aux")'
assert.raises 'Cyclic dependency', -> loader -> foo_load 'aux'

allows passing parameters to the loaded file

dir\join('aux.lua').contents = 'return ...'
assert.equal 123, loader -> foo_load 'aux', 123

(loading files from sub directories)

local sub_dir

before_each ->
  sub_dir = dir\join('subdir')
  sub_dir\mkdir!

supports both slashes and dots in the path

sub_dir\join('sub.lua').contents = 'return "sub"'
sub_dir\join('sub2.lua').contents = 'return "sub2"'

assert.equals 'sub', loader -> foo_load 'subdir/sub'
assert.equals 'sub2', loader -> foo_load 'subdir.sub2'

loads the file once regardless of whether dots or slashes are used

sub_dir\join('sub.lua').contents = [[
  _G.load_count = _G.load_count + 1
  return _G.load_count
]]
_G.load_count = 0
assert.equals 1, loader -> foo_load 'subdir/sub'
assert.equals 1, loader -> foo_load 'subdir.sub'

loads an implicit init file for bare directory references

sub_dir\join('init.lua').contents = 'return "lua"'
assert.equals 'lua', loader -> foo_load 'subdir'