-- $Id: attrib.lua,v 1.65 2016/11/07 13:11:28 roberto Exp $
-- See Copyright Notice in file all.lua

print "testing require"

assert(require"string" == string)
assert(require"math" == math)
assert(require"table" == table)
assert(require"io" == io)
assert(require"os" == os)
assert(require"coroutine" == coroutine)
assert(type(package.path) == "string")
assert(type(package.gopath) == "string")
assert(type(package.loaded) == "table")
assert(type(package.preload) == "table")

assert(type(package.config) == "string")
print("package config: "..string.gsub(package.config, "\n", "|"))

-- do
--   -- create a path with 'max' templates,
--   -- each with 1-10 repetitions of '?'
--   local max = _soft and 100 or 2000
--   local t = {}
--   for i = 1,max do t[i] = string.rep("?", i%10 + 1) end
--   t[#t + 1] = ";"    -- empty template
--   local path = table.concat(t, ";")
--   -- use that path in a search
--   local s, err = package.searchpath("xuxu", path)
--   -- search fails; check that message has an occurence of
--   -- '??????????' with ? replaced by xuxu and at least 'max' lines
--   assert(not s and
--          string.find(err, string.rep("xuxu", 10)) and
--          #string.gsub(err, "[^\n]", "") >= max)
--   -- path with one very long template
--   local path = string.rep("?", max)
--   local s, err = package.searchpath("xuxu", path)
--   assert(not s and string.find(err, string.rep('xuxu', max)))
-- end

do
  local oldpath = package.path
  package.path = {}
  local s, err = pcall(require, "no-such-file")
  assert(not s and string.find(err, "package.path"))
  package.path = oldpath
end

print('+')


-- The next tests for 'require' assume some specific directories and
-- libraries.

if not _port then --[

local dirsep = string.match(package.config, "^([^\n]+)\n")

-- auxiliary directory with C modules and temporary files
-- local DIR = "libs" .. dirsep

-- prepend DIR to a name and correct directory separators
-- local function D (x)
--   x = string.gsub(x, "/", dirsep)
--   return DIR .. x
-- end

-- prepend DIR and pospend proper C lib. extension to a name
-- local function DC (x)
--   local ext = (dirsep == '\\') and ".dll" or ".so"
--   return D(x .. ext)
-- end


-- local function createfiles (files, preextras, posextras)
--   for n,c in pairs(files) do
--     io.output(D(n))
--     io.write(string.format(preextras, n))
--     io.write(c)
--     io.write(string.format(posextras, n))
--     io.close(io.output())
--   end
-- end

-- function removefiles (files)
--   for n in pairs(files) do
--     os.remove(D(n))
--   end
-- end

local files = {
  ["names.lua"] = "do return {...} end\n",
  ["err.lua"] = "B = 15; a = a + 1;",
  ["synerr.lua"] = "B =",
  ["A.lua"] = "",
  ["B.lua"] = "assert(...=='B');require 'A'",
  ["A.lc"] = "",
  ["A"] = "",
  ["L"] = "",
  ["XXxX"] = "",
  ["C.lua"] = "package.loaded[...] = 25; require'C'",
}

AA = nil
local extras = [[
NAME = '%s'
REQUIRED = ...
return AA]]

-- createfiles(files, "", extras)

-- -- testing explicit "dir" separator in 'searchpath'
-- assert(package.searchpath("C.lua", D"?", "", "") == D"C.lua")
-- assert(package.searchpath("C.lua", D"?", ".", ".") == D"C.lua")
-- assert(package.searchpath("--x-", D"?", "-", "X") == D"XXxX")
-- assert(package.searchpath("---xX", D"?", "---", "XX") == D"XXxX")
-- assert(package.searchpath(D"C.lua", "?", dirsep) == D"C.lua")
-- assert(package.searchpath(".\\C.lua", D"?", "\\") == D"./C.lua")

local oldpath = package.path

package.path = string.gsub("D/?.lua;D/?.lc;D/?;D/??x?;D/L", "D/", DIR)

local try = function (p, n, r)
  NAME = nil
  local rr = require(p)
  assert(NAME == n)
  assert(REQUIRED == p)
  assert(rr == r)
end

-- a = require"names"
-- assert(a[1] == "names" and a[2] == D"names.lua")

-- _G.a = nil
-- local st, msg = pcall(require, "err")
-- assert(not st and string.find(msg, "arithmetic") and B == 15)
-- st, msg = pcall(require, "synerr")
-- assert(not st and string.find(msg, "error loading module"))

-- assert(package.searchpath("C", package.path) == D"C.lua")
-- assert(require"C" == 25)
-- assert(require"C" == 25)
-- AA = nil
-- try('B', 'B.lua', true)
-- assert(package.loaded.B)
-- assert(require"B" == true)
-- assert(package.loaded.A)
-- assert(require"C" == 25)
-- package.loaded.A = nil
-- try('B', nil, true)   -- should not reload package
-- try('A', 'A.lua', true)
-- package.loaded.A = nil
-- os.remove(D'A.lua')
-- AA = {}
-- try('A', 'A.lc', AA)  -- now must find second option
-- assert(package.searchpath("A", package.path) == D"A.lc")
-- assert(require("A") == AA)
-- AA = false
-- try('K', 'L', false)     -- default option
-- try('K', 'L', false)     -- default option (should reload it)
-- assert(rawget(_G, "_REQUIREDNAME") == nil)

-- AA = "x"
-- try("X", "XXxX", AA)


-- removefiles(files)


-- -- testing require of sub-packages

-- local _G = _G

-- package.path = string.gsub("D/?.lua;D/?/init.lua", "D/", DIR)

-- files = {
--   ["P1/init.lua"] = "AA = 10",
--   ["P1/xuxu.lua"] = "AA = 20",
-- }

-- createfiles(files, "_ENV = {}\n", "\nreturn _ENV\n")
-- AA = 0

-- local m = assert(require"P1")
-- assert(AA == 0 and m.AA == 10)
-- assert(require"P1" == m)
-- assert(require"P1" == m)

-- assert(package.searchpath("P1.xuxu", package.path) == D"P1/xuxu.lua")
-- m.xuxu = assert(require"P1.xuxu")
-- assert(AA == 0 and m.xuxu.AA == 20)
-- assert(require"P1.xuxu" == m.xuxu)
-- assert(require"P1.xuxu" == m.xuxu)
-- assert(require"P1" == m and m.AA == 10)


-- removefiles(files)


-- package.path = ""
-- assert(not pcall(require, "file_does_not_exist"))
-- package.path = "??\0?"
-- assert(not pcall(require, "file_does_not_exist1"))

-- package.path = oldpath

-- -- check 'require' error message
-- local fname = "file_does_not_exist2"
-- local m, err = pcall(require, fname)
-- for t in string.gmatch(package.path..";"..package.cpath, "[^;]+") do
--   t = string.gsub(t, "?", fname)
--   assert(string.find(err, t, 1, true))
-- end

-- do  -- testing 'package.searchers' not being a table
--   local searchers = package.searchers
--   package.searchers = 3
--   local st, msg = pcall(require, 'a')
--   assert(not st and string.find(msg, "must be a table"))
--   package.searchers = searchers
-- end

-- local function import(...)
--   local f = {...}
--   return function (m)
--     for i=1, #f do m[f[i]] = _G[f[i]] end
--   end
-- end

-- -- cannot change environment of a C function
-- assert(not pcall(module, 'XUXU'))



-- -- testing require of C libraries


-- local p = ""   -- On Mac OS X, redefine this to "_"

-- -- check whether loadlib works in this system
-- local st, err, when = package.loadlib(DC"lib1", "*")
-- if not st then
--   local f, err, when = package.loadlib("donotexist", p.."xuxu")
--   assert(not f and type(err) == "string" and when == "absent")
--   ;(Message or print)('\n >>> cannot load dynamic library <<<\n')
--   print(err, when)
-- else
--   -- tests for loadlib
--   local f = assert(package.loadlib(DC"lib1", p.."onefunction"))
--   local a, b = f(15, 25)
--   assert(a == 25 and b == 15)

--   f = assert(package.loadlib(DC"lib1", p.."anotherfunc"))
--   assert(f(10, 20) == "10%20\n")

--   -- check error messages
--   local f, err, when = package.loadlib(DC"lib1", p.."xuxu")
--   assert(not f and type(err) == "string" and when == "init")
--   f, err, when = package.loadlib("donotexist", p.."xuxu")
--   assert(not f and type(err) == "string" and when == "open")

--   -- symbols from 'lib1' must be visible to other libraries
--   f = assert(package.loadlib(DC"lib11", p.."luaopen_lib11"))
--   assert(f() == "exported")

--   -- test C modules with prefixes in names
--   package.cpath = DC"?"
--   local lib2 = require"lib2-v2"
--   -- check correct access to global environment and correct
--   -- parameters
--   assert(_ENV.x == "lib2-v2" and _ENV.y == DC"lib2-v2")
--   assert(lib2.id("x") == "x")

--   -- test C submodules
--   local fs = require"lib1.sub"
--   assert(_ENV.x == "lib1.sub" and _ENV.y == DC"lib1")
--   assert(fs.id(45) == 45)
-- end

-- _ENV = _G


-- -- testing preload

-- do
--   local p = package
--   package = {}
--   p.preload.pl = function (...)
--     local _ENV = {...}
--     function xuxu (x) return x+20 end
--     return _ENV
--   end

--   local pl = require"pl"
--   assert(require"pl" == pl)
--   assert(pl.xuxu(10) == 30)
--   assert(pl[1] == "pl" and pl[2] == nil)

--   package = p
--   assert(type(package.path) == "string")
-- end

print('+')

end  --]

-- print("testing assignments, logical operators, and constructors")

-- local res, res2 = 27

-- a, b = 1, 2+3
-- assert(a==1 and b==5)
-- a={}
-- function f() return 10, 11, 12 end
-- a.x, b, a[1] = 1, 2, f()
-- assert(a.x==1 and b==2 and a[1]==10)
-- a[f()], b, a[f()+3] = f(), a, 'x'
-- assert(a[10] == 10 and b == a and a[13] == 'x')

-- do
--   local f = function (n) local x = {}; for i=1,n do x[i]=i end;
--                          return table.unpack(x) end;
--   local a,b,c
--   a,b = 0, f(1)
--   assert(a == 0 and b == 1)
--   A,b = 0, f(1)
--   assert(A == 0 and b == 1)
--   a,b,c = 0,5,f(4)
--   assert(a==0 and b==5 and c==1)
--   a,b,c = 0,5,f(0)
--   assert(a==0 and b==5 and c==nil)
-- end

-- a, b, c, d = 1 and nil, 1 or nil, (1 and (nil or 1)), 6
-- assert(not a and b and c and d==6)

-- d = 20
-- a, b, c, d = f()
-- assert(a==10 and b==11 and c==12 and d==nil)
-- a,b = f(), 1, 2, 3, f()
-- assert(a==10 and b==1)

-- assert(a<b == false and a>b == true)
-- assert((10 and 2) == 2)
-- assert((10 or 2) == 10)
-- assert((10 or assert(nil)) == 10)
-- assert(not (nil and assert(nil)))
-- assert((nil or "alo") == "alo")
-- assert((nil and 10) == nil)
-- assert((false and 10) == false)
-- assert((true or 10) == true)
-- assert((false or 10) == 10)
-- assert(false ~= nil)
-- assert(nil ~= false)
-- assert(not nil == true)
-- assert(not not nil == false)
-- assert(not not 1 == true)
-- assert(not not a == true)
-- assert(not not (6 or nil) == true)
-- assert(not not (nil and 56) == false)
-- assert(not not (nil and true) == false)
-- assert(not 10 == false)
-- assert(not {} == false)
-- assert(not 0.5 == false)
-- assert(not "x" == false)

-- assert({} ~= {})
-- print('+')

-- a = {}
-- a[true] = 20
-- a[false] = 10
-- assert(a[1<2] == 20 and a[1>2] == 10)

-- function f(a) return a end

-- local a = {}
-- for i=3000,-3000,-1 do a[i + 0.0] = i; end
-- a[10e30] = "alo"; a[true] = 10; a[false] = 20
-- assert(a[10e30] == 'alo' and a[not 1] == 20 and a[10<20] == 10)
-- for i=3000,-3000,-1 do assert(a[i] == i); end
-- a[print] = assert
-- a[f] = print
-- a[a] = a
-- assert(a[a][a][a][a][print] == assert)
-- a[print](a[a[f]] == a[print])
-- assert(not pcall(function () local a = {}; a[nil] = 10 end))
-- assert(not pcall(function () local a = {[nil] = 10} end))
-- assert(a[nil] == nil)
-- a = nil

-- a = {10,9,8,7,6,5,4,3,2; [-3]='a', [f]=print, a='a', b='ab'}
-- a, a.x, a.y = a, a[-3]
-- assert(a[1]==10 and a[-3]==a.a and a[f]==print and a.x=='a' and not a.y)
-- a[1], f(a)[2], b, c = {['alo']=assert}, 10, a[1], a[f], 6, 10, 23, f(a), 2
-- a[1].alo(a[2]==10 and b==10 and c==print)


-- -- test of large float/integer indices 

-- -- compute maximum integer where all bits fit in a float
-- local maxint = math.maxinteger

-- while maxint - 1.0 == maxint - 0.0 do   -- trim (if needed) to fit in a float
--   maxint = maxint // 2
-- end

-- maxintF = maxint + 0.0   -- float version

-- assert(math.type(maxintF) == "float" and maxintF >= 2.0^14)

-- -- floats and integers must index the same places
-- a[maxintF] = 10; a[maxintF - 1.0] = 11;
-- a[-maxintF] = 12; a[-maxintF + 1.0] = 13;

-- assert(a[maxint] == 10 and a[maxint - 1] == 11 and
--        a[-maxint] == 12 and a[-maxint + 1] == 13)

-- a[maxint] = 20
-- a[-maxint] = 22

-- assert(a[maxintF] == 20 and a[maxintF - 1.0] == 11 and
--        a[-maxintF] == 22 and a[-maxintF + 1.0] == 13)

-- a = nil


-- -- test conflicts in multiple assignment
-- do
--   local a,i,j,b
--   a = {'a', 'b'}; i=1; j=2; b=a
--   i, a[i], a, j, a[j], a[i+j] = j, i, i, b, j, i
--   assert(i == 2 and b[1] == 1 and a == 1 and j == b and b[2] == 2 and
--          b[3] == 1)
-- end

-- -- repeat test with upvalues
-- do
--   local a,i,j,b
--   a = {'a', 'b'}; i=1; j=2; b=a
--   local function foo ()
--     i, a[i], a, j, a[j], a[i+j] = j, i, i, b, j, i
--   end
--   foo()
--   assert(i == 2 and b[1] == 1 and a == 1 and j == b and b[2] == 2 and
--          b[3] == 1)
--   local t = {}
--   (function (a) t[a], a = 10, 20  end)(1);
--   assert(t[1] == 10)
-- end

-- -- bug in 5.2 beta
-- local function foo ()
--   local a
--   return function ()
--     local b
--     a, b = 3, 14    -- local and upvalue have same index
--     return a, b
--   end
-- end

-- local a, b = foo()()
-- assert(a == 3 and b == 14)

print('OK')

-- return res

