-- ------------------------------------------------------------
-- Testes para shellExtension.lua
-- -----------------------------------------------------------

local sgaLibs = os.getenv("SGA_LIBS_DIR")
if not sgaLibs then
	print("[ERROR] Env var SGA_LIBS_DIR not defined!")
	os.exit(-1)
end
local shellExtension = sgaLibs.."/shellExtension.lua"
dofile(shellExtension)

local ext = require "shellExtension"

dofile("test/lunity.lua")
require "lunity"

module( 'TEST_SHELL_EXTENSION', lunity )

local SANDBOX_BASE_DIR = "/tmp/sandbox"
local SANDBOX = nil

-- ------------------------------------------------------------
-- Funções utilitárias para os testes
-- ------------------------------------------------------------
function _execute (cmd, shell)
	if not shell then
		shell = "ksh"
	end
	local shell_cmd = string.format("%s -c \"%s\"", shell, cmd)
	return (os.execute(shell_cmd) == 0)
end

function _mkdir (dirname)
	return _execute("mkdir -p '"..dirname.."'")
end

function _mkdirSandbox (dirname)
	local newDirName = _nameInSandbox(dirname)
	_mkdir(newDirName)
	return newDirName
end

function _isDir (dirname)
	return _execute("test -d '"..dirname.."'")
end

function _nameInSandbox (name)
	return SANDBOX.."/"..name
end

function _isFile (filename)
	return _execute("test -f '"..filename.."'")
end

function _touch (filename)
	return _execute("touch '"..filename.."'")
end

function _touchSandbox (filename)
    local newFileName = _nameInSandbox(filename)
	_touch(newFileName)
	return newFileName
end

function _remove (filename)
	return _execute("rm -rf '"..filename.."'")
end

function _removeSandbox (filename)
	return _remove(_nameInSandbox(filename))
end

function _getRandomFileName ()
	local randomFileName = os.tmpname()
	os.remove(randomFileName)
	randomFileName = string.gsub(randomFileName, "/tmp/", "")
	return _nameInSandbox(randomFileName)
end

function _createRandomFile ()
	local name = _getRandomFileName()
	_touch(name)
	return name
end

function _createRandomDir ()
	local name = _getRandomFileName()
	_mkdir(name)
	return name
end

function _writeFile (filename, content)
	local file = io.open(filename, "w")
	assertNotNil(file)
	file:write(content)
	file:close()
end

function _readFile (filename)
	local file = io.open(filename, "r")
	assertNotNil(file)
	local content = file:read("*a")
	file:close()
	return content
end

function _pwd()
	local file = io.popen("pwd")
	local currentDir = string.gsub(file:read("*l"), "%s+$", "")
	file:close()
	return currentDir
end

function _split (list)
	if #_trim(list) > 0 then
    	local sep = "\n"
		local splittedList = {}
		list:gsub("([^"..sep.."]*)"..sep, function(c) table.insert(splittedList, c) end)
		return splittedList
	else
		return nil
	end
end

function assertTableEqual(t1, t2)
	if (t1 and not t2) or (t2 and not t1) then
		if t1 then error("Tables not equal; expected table is null") end
		if t2 then error("Tables not equal; actual table is null") end
	else
		return assertTableEquals(table.sort(t1), table.sort(t2))
	end
end

function _trim (s)
    return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
end

-- ------------------------------------------------------------
-- Funções de inicialização
-- ------------------------------------------------------------

function setup()
	local randomFileName = os.tmpname()
	os.remove(randomFileName)
	SANDBOX = SANDBOX_BASE_DIR..randomFileName.."_test_sandbox"
	if not _mkdir(SANDBOX) then
		print("[ERROR] Could not create test sandbox")
		os.exit(-1)
	end
	ext.chdir(SANDBOX)
end

function teardown()
	if not _remove(SANDBOX) then
		print("[WARNING] Could not remove test sandbox")
	end
	SANDBOX = nil
end

-- ------------------------------------------------------------
-- Testes para getParameterValue (command, name)
-- ------------------------------------------------------------

function testGetParameterValueWithValidParameter ()
	local args = {}
	args[-1] = "lua5.1"
	args[0] = "/tmp/someScript.lua"
	args[1] = "PARAM_NAME=PARAM_VALUE"
	args[2] = "PARAM_NAME2=PARAM_VALUE2"
	local value, err = ext.getParameterValue(args, "PARAM_NAME")
	assertNil(err)
	assertEqual(value, "PARAM_VALUE")
end

function testGetParameterValueFromAbsentParameter ()
	local args = {}
	args[-1] = "lua5.1"
	args[0] = "/tmp/someScript.lua"
	args[1] = "PARAM_NAME=PARAM_VALUE"
	args[2] = "PARAM_NAME2=PARAM_VALUE2"
	local value, err = ext.getParameterValue(args, "PARAM_NOT_IN_CMD_LINE")
	assertTrue(is_string(err))
	assertNil(value)
end

function testGetParameterValueFromEmptyArgs ()
	local args = {}
	args[-1] = "lua5.1"
	args[0] = "/tmp/someScript.lua"
	local value, err = ext.getParameterValue(args, "ANY_PARAM_NAME")
	assertTrue(is_string(err))
	assertNil(value)
end

function testGetParameterValueFromEmptyParam ()
	local args = {}
	args[-1] = "lua5.1"
	args[0] = "/tmp/someScript.lua"
	args[1] = "PARAM_NAME=PARAM_VALUE"
	args[2] = "PARAM_NAME2=PARAM_VALUE2"
	local value, err = ext.getParameterValue({}, "")
	assertTrue(is_string(err))
	assertNil(value)
end

-- ------------------------------------------------------------
-- Testes para strLineIterator (text)
-- ------------------------------------------------------------

function testStrLineIteratorWithEmptyText ()
	local i = 0
	for line in ext.strLineIterator("") do
		i = i + 1
	end
	assertEqual(i, 0)	
end

function testStrLineIteratorWithEmptyLines ()
	local line1 = "line1 line1 line1.\n"
	local line2 = "\n"
	local line3 = "line3 line3 line3.\n"
	local line4 = "\n"
	local text = line1..line2..line3..line4
	local i = 0
	for line in ext.strLineIterator(text) do
		i = i + 1
		if i % 2 == 0 then
			assertEqual(line, "")
		else
			assertEqual (line, "line"..i.." line"..i.." line"..i..".")
		end
	end
	assertEqual(i, 4)	
end

function testStrLineIteratorWithSingleLine ()
	local line1 = "line1 line1 line1."
	local i = 0
	for line in ext.strLineIterator(line1) do
		i = i + 1
		assertEqual(line, line1)
	end
	assertEqual(i, 1)
end

function testStrLineIteratorWithMultipleLines ()
	local line1 = "line1 line1 line1.\n"
	local line2 = "line2 line2 line2.\n"
	local line3 = "line3 line3 line3.\n"
	local text = line1..line2..line3
	local i = 0
	for line in ext.strLineIterator(text) do
		i = i + 1
		assertEqual(line, "line"..i.." line"..i.." line"..i..".")
	end
	assertEqual(i, 3)
end

-- ------------------------------------------------------------
-- Testes para strReplaceAll (str, patt, repl)
-- ------------------------------------------------------------

function testStrReplaceAllWithSingleReplaceString ()
	local original = "ab_REPLACE_cd"
	local result = ext.strReplaceAll(original, "_REPLACE_", "_REPLACED_")
	assertEqual(result, "ab_REPLACED_cd")
end

function testStrReplaceAllWithMultipleReplaceStrings ()
	local original = "_REPLACE_a_REPLACE_bc_REPLACE_d_REPLACE_"
	local result = ext.strReplaceAll(original, "_REPLACE_", "_REPLACED_")
	assertEqual(result, "_REPLACED_a_REPLACED_bc_REPLACED_d_REPLACED_")
end

function testStrReplaceAllWithNothingToReplace ()
	local original = "abcd"
	local result = ext.strReplaceAll(original, "_NOT_ON_ORIGINAL_STRING_", "_REPLACED_")
	assertEqual(result, original)
end

-- ------------------------------------------------------------
-- Testes para strRemoveDuplicates (str, dupl)
-- ------------------------------------------------------------

function testStrRemoveDuplicatesWithSingleDuplicates ()
	local original = "ab\\\\cd"
	local result = ext.strRemoveDuplicates(original, "\\")
	assertEqual(result, "ab\\cd")
end

function testStrRemoveDuplicatesWithMultipleDuplicates ()
	local original = "a\\\\b\\\\c\\\\d"
	local result = ext.strRemoveDuplicates(original, "\\")
	assertEqual(result, "a\\b\\c\\d")
end

function testStrRemoveDuplicatesWithNoDuplicates ()
	local original = "abc"
	local result = ext.strRemoveDuplicates(original, "\\")
	assertEqual(result, original)
end

-- ------------------------------------------------------------
-- Testes para strGetFirstLine (text)
-- ------------------------------------------------------------

function testStrGetFirstLineWithMultipleLines ()
	local line1 = "line1 line1 line1."
	local line2 = "line2 line2 line2."
	local line3 = "line3 line3 line3."
	local text = line1.."\n"..line2.."\n"..line3
	local result = ext.strGetFirstLine(text)
	assertEqual(result, line1)
end

function testStrGetFirstLineWithSingleLine ()
	local line1 = "line1 line1 line1."
	local result = ext.strGetFirstLine(line1)
	assertEqual(result, line1)
end

function testStrGetFirstLineWithEmptyFirstLine ()
	local line1 = ""
	local line2 = "line2 line2 line2."
	local line3 = "line3 line3 line3."
	local text = line1.."\n"..line2.."\n"..line3
	local result = ext.strGetFirstLine(text)
	assertEqual(result, line1)
end

function testStrGetFirstLineWithEmptyText ()
	local emptyText = "\n"
	local result = ext.strGetFirstLine(emptyText)
	assertEqual(result, "")
end

-- ------------------------------------------------------------
-- Testes para strCaseEscape (str)
-- ------------------------------------------------------------

function testStrCaseEscapeWithSingleChar ()
	local str = "a"
	local result = ext.strCaseEscape(str)
	assertEqual(result, "[aA]")
end

function testStrCaseEscapeWithMultipleChars ()
	local str = "abcdef"
	local result = ext.strCaseEscape(str)
	assertEqual(result, "[aA][bB][cC][dD][eE][fF]")
end

function testStrCaseEscapeWithEmptyStr ()
	local emptyStr = ""
	local result = ext.strCaseEscape(emptyStr)
	assertEqual(result, emptyStr)
end

function testStrCaseEscapeWithSymbolChars ()
	local str = "a.b/c:d\"e~f12"
	local result = ext.strCaseEscape(str)
	assertEqual(result, "[aA].[bB]/[cC]:[dD]\"[eE]~[fF]12")
end

-- ------------------------------------------------------------
-- Testes para regexpEscape (str, caseSensitive)
-- ------------------------------------------------------------

function testRegexpEscapeWithSimpleChars ()
	local str = "abc"
	local result = ext.regexpEscape(str)
	assertEqual(result, "[aA][bB][cC]")
end

function testRegexpEscapeWithSymbolChars ()
	local str = "ab-c.def"
	local result = ext.regexpEscape(str)
	assertEqual(result, "[aA][bB]%-[cC]%.[dD][eE][fF]")
end

function testRegexpEscapeWithCaseSensitiveChars ()
	local str = "aB-c.dEf"
	local result = ext.regexpEscape(str, true)
	assertEqual(result, "aB%-c%.dEf")
end

function testRegexpEscapeWithEmptyStr ()
	local emptyStr = ""
	local result = ext.regexpEscape(emptyStr)
	assertEqual(result, emptyStr)
end

function testRegexpEscapeWithNonEscapedSymbolChars ()
	local str = "a.b/c:d\"e~f-12"
	local result = ext.regexpEscape(str)
	assertEqual(result, "[aA]%.[bB]/[cC]:[dD]\"[eE]~[fF]%-12")
end

-- ------------------------------------------------------------
-- Testes para quoteEscape (str)
-- ------------------------------------------------------------

function testQuoteEscapeWithMultipleEscapes ()
	local str = "a\\b\\c"
	local result = ext.quoteEscape(str)
	assertEqual(result, "a\\\\b\\\\c")
end

function testQuoteEscapeWithEmptyStr ()
	local emptyStr = ""
	local result = ext.quoteEscape(emptyStr)
	assertEqual(result, emptyStr)
end

function testQuoteEscapeWithSingleEscape ()
	local str = "\\"
	local result = ext.quoteEscape(str)
	assertEqual(result, "\\\\")
end

function testQuoteEscapeWithNoEscape ()
	local str = "abcd"
	local result = ext.quoteEscape(str)
	assertEqual(result, str)
end

-- ------------------------------------------------------------
-- Testes para splitPath (path)
-- ------------------------------------------------------------

function testSplitPath ()
	local path = "/dir/subdir/file.ext"
	local dir, file = ext.splitPath(path)
	assertEqual(dir, "/dir/subdir/")
	assertEqual(file, "file.ext")
end

function testSplitPathWithSpaceInPath ()
	local path = "/dir with space/sub dir with space/file with space.ext"
	local dir, file = ext.splitPath(path)
	assertEqual(dir, "/dir with space/sub dir with space/")
	assertEqual(file, "file with space.ext")
end

function testSplitPathWithDirAtEnd ()
	local path = "/dir/subdir/subdir2/"
	local dir, file = ext.splitPath(path)
	assertEqual(dir, "/dir/subdir/")
	assertEqual(file, "subdir2/")
end

function testSplitPathWithEmptyPath ()
	local path = ""
	local dir, file = ext.splitPath(path)
	assertEqual(dir, "")
	assertEqual(file, "")
end

function testSplitPathWithSingleFileComponent ()
	local path = "file.ext"
	local dir, file = ext.splitPath(path)
	assertEqual(dir, "")
	assertEqual(file, path)
end

function testSplitPathWithSingleDirComponent ()
	local path = "file/"
	local dir, file = ext.splitPath(path)
	assertEqual(dir, "")
	assertEqual(file, path)
end

function testSplitPathWithHomeComponent ()
	local path = "~/subdir/file.ext"
	local dir, file = ext.splitPath(path)
	assertEqual(dir, "~/subdir/")
	assertEqual(file, "file.ext")
end

function testSplitPathWithRelativeComponents ()
	local path = "../subdir/../file.ext"
	local dir, file = ext.splitPath(path)
	assertEqual(dir, "../subdir/../")
	assertEqual(file, "file.ext")
end

function testSplitPathWithCurrentDirComponent ()
	local path = "./subdir/file.ext"
	local dir, file = ext.splitPath(path)
	assertEqual(dir, "./subdir/")
	assertEqual(file, "file.ext")
end

-- ------------------------------------------------------------
-- Testes para toStringArray (valueList)
-- ------------------------------------------------------------

function testToStringArrayWithMultipleStrings ()
	local valueList = "aa,b/b,c c"
	local result = ext.toStringArray(valueList)	
	assertTableEqual(result, { "aa", "b/b", "c c" })
end

function testToStringArrayWithMultipleStringsEndedByComma ()
	local valueList = "aa,b/b,c c,"
	local result = ext.toStringArray(valueList)	
	assertTableEqual(result, { "aa", "b/b", "c c" })
end

function testToStringArrayWithSingleString ()
	local valueList = "aa"
	local result = ext.toStringArray(valueList)	
	assertTableEqual(result, { "aa" })
end

function testToStringArrayWithEmptyString ()
	local valueList = ""
	local result = ext.toStringArray(valueList)	
	assertTableEqual(result, { })
end

-- ------------------------------------------------------------
-- Testes para splitWithLineFeed (valueList)
-- ------------------------------------------------------------

function testSplitWithLineFeedWithMultipleStrings ()
	local valueList = "aa,b/b,c c"
	local result = ext.splitWithLineFeed(valueList)	
	assertEqual(result, "aa\nb/b\nc c")
end

function testSplitWithLineFeedWithMultipleStringsEndedByComma ()
	local valueList = "aa,b/b,c c,"
	local result = ext.splitWithLineFeed(valueList)	
	assertEqual(result, "aa\nb/b\nc c\n")
end

function testSplitWithLineFeedWithSingleString ()
	local valueList = "aa"
	local result = ext.splitWithLineFeed(valueList)	
	assertEqual(result, "aa")
end

function testSplitWithLineFeedWithEmptyString ()
	local valueList = ""
	local result = ext.splitWithLineFeed(valueList)	
	assertEqual(result, "")
end

function testSplitWithLineFeedWithAlternativeSeparators ()
	local valueList = "aa,b/b,c c"
	local result = ext.splitWithLineFeed(valueList, ".", "/")	
	assertEqual(result, "aa,b.b,c c")
end

-- ------------------------------------------------------------
-- Testes para fileExists (file)
-- ------------------------------------------------------------

function testFileExistsWithExistingFile () 
	local fileName = _createRandomFile()
	local result = ext.fileExists(fileName)
	assertTrue(result)
end

function testFileExistsWithSpaceInFileName () 
	local fileName = "file name with space.txt"
	local sandboxFile = _touchSandbox(fileName)
	local fileWasCreated = _isFile(sandboxFile)
	assertTrue(fileWasCreated)
	local result = ext.fileExists(sandboxFile)
	assertTrue(result)
end

function testFileExistsWithNonExistingFile () 
	local fileName = _getRandomFileName() 
	local result = ext.fileExists(fileName)
	assertFalse(result)
end

-- ------------------------------------------------------------
-- Testes para isDir (dir)
-- ------------------------------------------------------------

function testIsDirWithExistingDir () 
	local dirname = _createRandomDir()
	local result = ext.isDir(dirname)
	assertTrue(result)
end

function testIsDirWithSpaceInDirName () 
	local dirname = "dir name with space"
	local sandboxDirName = _mkdirSandbox(dirname)
	local dirWasCreated = _isDir(sandboxDirName)
	assertTrue(dirWasCreated)
	local result = ext.isDir(dirname)
	assertTrue(result)
end

function testIsDirWithExistingFile () 
	local fileName = _createRandomFile()
	local result = ext.isDir(fileName)
	assertFalse(result)
end

function testIsDirWithNonExistingDir () 
	local dirname = _getRandomFileName()
	local result = ext.isDir(dirname)
	assertFalse(result)
end

-- ------------------------------------------------------------
-- Testes para ls (dir, arg)
-- ------------------------------------------------------------
function testLsWithEmptyDir ()
	local dirname = "emptyDir"
	local sandboxDirName = _mkdirSandbox(dirname)
	local dirWasCreated = _isDir(sandboxDirName)
	local result, err = ext.ls(dirname)
	assertType(result, 'table')
	assertTrue(#result == 0)
	assertNil(err)
end

function testLsDirWithOneFile ()
	local dirname = "oneFileDir"
	local sandboxDirName = _mkdirSandbox(dirname)
	local dirWasCreated = _isDir(sandboxDirName)
	_touchSandbox(dirname.."/teste.txt")
	local result, err = ext.ls(dirname)
	assertType(result, 'table')
	assertTrue(#result == 1)
	assertNil(err)
end

function testLsWithArgLOneFile ()
	local dirname = "oneFileDir"
	local sandboxDirName = _mkdirSandbox(dirname)
	local dirWasCreated = _isDir(sandboxDirName)
	_touchSandbox(dirname.."/teste.txt")
	local result, err = ext.ls(dirname, "-l")
	assertType(result, 'table')
	assertTrue(#result == 2)
	assertNil(err)
end

function testLsWithArgLTwoFiles ()
	local dirname = "oneFileDir"
	local sandboxDirName = _mkdirSandbox(dirname)
	local dirWasCreated = _isDir(sandboxDirName)
	_touchSandbox(dirname.."/teste1.txt")
	_touchSandbox(dirname.."/teste2.txt")
	local result, err = ext.ls(dirname, "-l")
	assertType(result, 'table')
	assertTrue(#result == 3)
	assertNil(err)
end

function testLsWithArgGOneFile ()
	local dirname = "oneFileDir"
	local sandboxDirName = _mkdirSandbox(dirname)
	local dirWasCreated = _isDir(sandboxDirName)
	_touchSandbox(dirname.."/teste.txt")
	local result, err = ext.ls(dirname, "-g")
	assertType(result, 'table')
	assertTrue(#result == 2)
	assertNil(err)
end

function testLsWithArgGTwoFiles ()
	local dirname = "oneFileDir"
	local sandboxDirName = _mkdirSandbox(dirname)
	local dirWasCreated = _isDir(sandboxDirName)
	_touchSandbox(dirname.."/teste1.txt")
	_touchSandbox(dirname.."/teste2.txt")
	local result, err = ext.ls(dirname, "-g")
	assertType(result, 'table')
	assertTrue(#result == 3)
	assertNil(err)
end

function testLsWithArgGOOneFile ()
	local dirname = "oneFileDir"
	local sandboxDirName = _mkdirSandbox(dirname)
	local dirWasCreated = _isDir(sandboxDirName)
	_touchSandbox(dirname.."/teste.txt")
	local result, err = ext.ls(dirname, "-go")
	assertType(result, 'table')
	assertTrue(#result == 2)
	assertNil(err)
end

function testLsWithArgGOTwoFiles ()
	local dirname = "oneFileDir"
	local sandboxDirName = _mkdirSandbox(dirname)
	local dirWasCreated = _isDir(sandboxDirName)
	_touchSandbox(dirname.."/teste1.txt")
	_touchSandbox(dirname.."/teste2.txt")
	local result, err = ext.ls(dirname, "-go")
	assertType(result, 'table')
	assertTrue(#result == 3)
	assertNil(err)
end

function testLsWithEmptyDirAndArgA ()
	local dirname = "emptyDir"
	local sandboxDirName = _mkdirSandbox(dirname)
	local dirWasCreated = _isDir(sandboxDirName)
	local result, err = ext.ls(dirname, "-a")
	assertType(result, 'table')
	assertTrue(#result == 2)
	assertNil(err)
end

function testLsDirWithOneFile ()
	local dirname = "oneFileDir"
	local sandboxDirName = _mkdirSandbox(dirname)
	local dirWasCreated = _isDir(sandboxDirName)
	_touchSandbox(dirname.."/teste.txt")
	local result, err = ext.ls(dirname, "-a")
	assertType(result, 'table')
	assertTrue(#result == 3)
	assertNil(err)
end

function testLsWithEmptyDirAndArgAGO ()
	local dirname = "emptyDir"
	local sandboxDirName = _mkdirSandbox(dirname)
	local dirWasCreated = _isDir(sandboxDirName)
	local result, err = ext.ls(dirname, "-ago")
	assertType(result, 'table')
	assertTrue(#result == 3)
	assertNil(err)
end

function testLsDirWithOneFileAndArgAGO ()
	local dirname = "oneFileDir"
	local sandboxDirName = _mkdirSandbox(dirname)
	local dirWasCreated = _isDir(sandboxDirName)
	_touchSandbox(dirname.."/teste.txt")
	local result, err = ext.ls(dirname, "-ago")
	assertType(result, 'table')
	assertTrue(#result == 4)
	assertNil(err)
end

function testLsMaliciousWithPipe ()
	local result, err = ext.ls(dirname, "-ago | rm -rf file.txt")
	assertNil(result)
	assertNotNil(err)
end

function testLsMaliciousWithSemicolon ()
	local result, err = ext.ls(dirname, "-ago; rm -rf file.txt")
	assertNil(result)
	assertNotNil(err)
end

function testLsMaliciousWithAnd ()
	local result, err = ext.ls(dirname, "-ago & rm -rf file.txt")
	assertNil(result)
	assertNotNil(err)
end

function testLsMaliciousWithDoubleAnd ()
	local result, err = ext.ls(dirname, "-ago && rm -rf file.txt")
	assertNil(result)
	assertNotNil(err)
end

-- ------------------------------------------------------------
-- Testes para isEmptyDir (dir)
-- ------------------------------------------------------------

function testIsEmptyDirWithExistingEmptyDir () 
	local dirname =  _createRandomDir()
	local result = ext.isEmptyDir(dirname)
	assertTrue(result)
end

function testIsEmptyDirWithExistingNonEmptyDir () 
	local dirname =  _createRandomDir()
	local file = dirname.."/name.txt"
	_touch(file)
	local result = ext.isEmptyDir(dirname)
	assertFalse(result)
end

function testIsEmptyDirWithSpaceInDirName () 
	local dirname = "empty dir name with space"
	local sandboxDirName = _mkdirSandbox(dirname)
	local dirWasCreated = _isDir(sandboxDirName)
	assertTrue(dirWasCreated)
	local result = ext.isEmptyDir(sandboxDirName)
	assertTrue(result)
end

function testIsEmptyDirWithExistingFile () 
	local fileName = _createRandomFile()
	local result = ext.isEmptyDir(fileName)
	assertFalse(result)
end

function testIsEmptyDirWithNonExistingDir () 
	local dirname =  _getRandomFileName()
	local result = ext.isEmptyDir(dirname)
	assertFalse(result)
end

-- ------------------------------------------------------------
-- Testes para mkdir (dir)
-- ------------------------------------------------------------

function testMkDirWithNonExistingDir () 
	local dirname =  _getRandomFileName()
	local result = ext.mkdir(dirname)
	local dirWasCreated = _isDir(dirname)
	assertTrue(result)
	assertTrue(dirWasCreated)
end

function testMkDirWithSpaceInDirName () 
	local dirname = "new dir name with space"
	local result = ext.mkdir(dirname)
	local dirWasCreated = _isDir(_nameInSandbox(dirname))
	assertTrue(result)
	assertTrue(dirWasCreated)
end

function testMkDirWithExistingDir () 
	local dirname =  _createRandomDir()
	local result = ext.mkdir(dirname)
	local dirWasCreated = _isDir(dirname)
	assertFalse(result)
	assertTrue(dirWasCreated)
end

-- ------------------------------------------------------------
-- Testes para mkdirs (dir)
-- ------------------------------------------------------------

function testMkDirsWithNonExistingDir () 
	local dirname =  _getRandomFileName()
	local result = ext.mkdirs(dirname)
	local dirWasCreated = _isDir(dirname)
	assertTrue(result)
	assertTrue(dirWasCreated)
end

function testMkDirsWithSpaceInDirName () 
	local dirname =  _getRandomFileName().."/subdir name with space"
	local result = ext.mkdirs(dirname)
	local dirWasCreated = _isDir(dirname)
	assertTrue(result)
	assertTrue(dirWasCreated)
end

function testMkDirsWithNonExistingSubDir () 
	local dirname =  _getRandomFileName().."/subdir"
	local result = ext.mkdirs(dirname)
	local dirWasCreated = _isDir(dirname)
	assertTrue(result)
	assertTrue(dirWasCreated)
end

function testMkDirsWithExistingDir () 
	local dirname =  _createRandomDir()
	local result = ext.mkdirs(dirname)
	local dirWasCreated = _isDir(dirname)
	assertTrue(result)
	assertTrue(dirWasCreated)
end

-- ------------------------------------------------------------
-- Testes para rmdir (dir)
-- ------------------------------------------------------------

function testRmDirWithEmptyDir () 
	local dirname =  _createRandomDir()
	local result = ext.rmdir(dirname)
	local wasRemoved = not _isDir(dirname)
	assertTrue(result)
	assertTrue(wasRemoved)
end

function testRmDirWithSpaceInDirName () 
	local dirname = "dir name with space"
	local sandboxDirName = _mkdirSandbox(dirname)
	local dirWasCreated = _isDir(sandboxDirName)
	assertTrue(dirWasCreated)
	local result = ext.rmdir(dirname)
	local wasRemoved = not _isDir(dirname)
	assertTrue(result)
	assertTrue(wasRemoved)
end

function testRmDirWithNonEmptyDir () 
	local dirname =  _createRandomDir()
	local file = dirname.."/name.txt"
	_touch(file)
	local result = ext.rmdir(dirname)
	local wasRemoved = not _isDir(dirname)
	assertTrue(result)
	assertTrue(wasRemoved)
end

function testRmDirWithNonExistingDir () 
	local dirname =  _getRandomFileName()
	local result = ext.rmdir(dirname)
	assertNil(result)
end

function testRmDirWithFile () 
	local filename =  _createRandomFile()
	local result = ext.rmdir(filename)
	assertNil(result)
end

-- ------------------------------------------------------------
-- Testes para shrinkDir (dir)
-- ------------------------------------------------------------

function testShrinkDirWithSimpleRelativePath ()
	local path = "/xx/yy/../zz/"
	local result = ext.shrinkDir(path)
	assertEqual(result, "/xx/zz/")
end

function testShrinkDirWithDoubleRelativePath ()
	local path = "xx/yy/../../zz"
	local result = ext.shrinkDir(path)
	assertEqual(result, "zz")
end

function testShrinkDirWithCurrentDirRelativePath ()
	local path = "/./xx/yy"
	local result = ext.shrinkDir(path)
	assertEqual(result, "/xx/yy")
end

function testShrinkDirWithNetworkRelativePath ()
	local path = "//xx/yy"
	local result = ext.shrinkDir(path)
	assertEqual(result, "/xx/yy")
end

function testShrinkDirWithSpaceInPath ()
	local path = "/x x/ yy/../zz "
	local result = ext.shrinkDir(path)
	assertEqual(result, "/x x/zz ")
end


function testShrinkDirWithNonRelativePath ()
	local path = "/xx/yy/zz"
	local result = ext.shrinkDir(path)
	assertEqual(result, path)
end

-- ------------------------------------------------------------
-- Testes para chdir (dir)
-- ------------------------------------------------------------

function testChdirWithAbsolutePath ()
	local dir = "/tmp"
	local result = ext.chdir(dir)
	assertEqual(result, dir)
end

function testChdirWithRelativePath ()
	local subdir = "subdir"
	local result = ext.chdir(subdir)
	local expected = _nameInSandbox(subdir)
	assertEqual(result, expected)
end

function testChdirWithSpaceInPath ()
	local dirname = "dir name with space"
	local result = ext.chdir(dirname)
	local expected = _nameInSandbox(dirname)
	assertEqual(result, expected)
end

function testChdirWithEmptyPath ()
	local dirname = ""
	local result = ext.chdir(dirname)
	local expected = _nameInSandbox(dirname)
	assertEqual(result, expected)
end

-- ------------------------------------------------------------
-- Testes para getenv (var)
-- ------------------------------------------------------------

function testGetEnvWithExistingVar ()
	local result = ext.getenv("$")
	assertNotNil(result)
end

function testGetEnvWithNonExistingVar ()
	local result = ext.getenv("NON_EXISTING_ENV_VAR")
	assertEqual(result, "")
end

-- ------------------------------------------------------------
-- Testes para fileCopy (from, to)
-- ------------------------------------------------------------

function testFileCopyWithExistingOriginFile ()
	local origin = _createRandomFile()
	local target = origin.."_TARGET"
	local originContent = "line1 line1 line1\nline2 line2 line2\n"
	_writeFile(origin, originContent)
	local result = ext.fileCopy(origin, target)
	local targetExists = _isFile(target)
	local originExists = _isFile(origin)
	local targetContent = _readFile(target)
	assertTrue(result)
	assertTrue(targetExists)
	assertTrue(originExists)
	assertEqual(targetContent, originContent)
end

function testFileCopyWithSpaceInFileName ()
	local origin = "file name wih space"
	local sandboxOrigin = _touchSandbox(origin)
	local target = sandboxOrigin.." TARGET"
	local originContent = "line1 line1 line1\nline2 line2 line2\n"
	_writeFile(sandboxOrigin, originContent)
	local result = ext.fileCopy(origin, target)
	local targetExists = _isFile(target)
	local originExists = _isFile(sandboxOrigin)
	local targetContent = _readFile(target)
	assertTrue(result)
	assertTrue(targetExists)
	assertTrue(originExists)
	assertEqual(targetContent, originContent)
end

function testFileCopyWithExistingTargetFile ()
	local origin = _createRandomFile()
	local target = _createRandomFile()
	local originContent = "line1 line1 line1\nline2 line2 line2\n"
	_writeFile(origin, originContent)
	local result = ext.fileCopy(origin, target)
	local targetExists = _isFile(target)
	local originExists = _isFile(origin)
	local targetContent = _readFile(target)
	assertTrue(result)
	assertTrue(targetExists)
	assertTrue(originExists)
	assertEqual(targetContent, originContent)
end

function testFileCopyWithNonExistingOriginFile ()
	local target = _createRandomFile()
	local origin = target.."_ORIGIN"
	local result = ext.fileCopy(origin, target)
	assertFalse(result)
end

-- ------------------------------------------------------------
-- Testes para fileMove (from, to)
-- ------------------------------------------------------------

function testFileMoveWithExistingOriginFile ()
	local origin = _createRandomFile()
	local target = origin.."_TARGET"
	local originContent = "line1 line1 line1\nline2 line2 line2\n"
	_writeFile(origin, originContent)
	local result = ext.fileMove(origin, target)
	local targetExists = _isFile(target)
	local originExists = _isFile(origin)
	local targetContent = _readFile(target)
	assertTrue(result)
	assertTrue(targetExists)
	assertFalse(originExists)
	assertEqual(targetContent, originContent)
end

function testFileMoveWithSpaceInFileName ()
	local origin = "file name wih space"
    local sandboxOrigin = _touchSandbox(origin)
	local target = sandboxOrigin.." TARGET"
	local originContent = "line1 line1 line1\nline2 line2 line2\n"
	_writeFile(sandboxOrigin, originContent)
	local result = ext.fileMove(origin, target)
	local targetExists = _isFile(target)
	local originExists = _isFile(sandboxOrigin)
	local targetContent = _readFile(target)
	assertTrue(result)
	assertTrue(targetExists)
	assertFalse(originExists)
	assertEqual(targetContent, originContent)
end

function testFileMoveWithExistingTargetFile ()
	local origin = _createRandomFile()
	local target = _createRandomFile()
	local originContent = "line1 line1 line1\nline2 line2 line2\n"
	_writeFile(origin, originContent)
	local result = ext.fileMove(origin, target)
	local targetExists = _isFile(target)
	local originExists = _isFile(origin)
	local targetContent = _readFile(target)
	assertTrue(result)
	assertTrue(targetExists)
	assertFalse(originExists)
	assertEqual(targetContent, originContent)
end

function testFileMoveWithNonExistingOriginFile ()
	local target = _getRandomFileName()
	local origin = target.."_ORIGIN"
	local result = ext.fileMove(origin, target)
	assertFalse(result)
end

-- ------------------------------------------------------------
-- Testes para fileAppend (fileName, text)
-- ------------------------------------------------------------

function testFileAppendWithExistingFile ()
	local fileName = _createRandomFile()
	local content = "line1 line1 line1\n"
	_writeFile(fileName, content)
	local textToAppend = "line2 line2 line2\n"
	ext.fileAppend(fileName, textToAppend)
	local newContent = _readFile(fileName)
	assertEqual(newContent, content..textToAppend)
end

function testFileAppendWithSpaceInFileName ()
	local fileName = "file name with space"
	local sandboxFileName = _touchSandbox(fileName)
	local content = "line1 line1 line1\n"
	_writeFile(sandboxFileName, content)
	local textToAppend = "line2 line2 line2\n"
	ext.fileAppend(fileName, textToAppend)
	local newContent = _readFile(sandboxFileName)
	assertEqual(newContent, content..textToAppend)
end

function testFileAppendWithNonExistingFile ()
	local fileName = _getRandomFileName()
	local textToAppend = "line2 line2 line2\n"
	ext.fileAppend(fileName, textToAppend)
	local content = _readFile(fileName)
	assertEqual(content, textToAppend)
end

-- ------------------------------------------------------------
-- Testes para fileRemove (name)
-- ------------------------------------------------------------

function testFileRemoveWithExistingFile ()
	local fileName = _createRandomFile()
	local result = ext.fileRemove(fileName)
	local fileWasRemoved = not _isFile(fileName)
	assertTrue(result)
	assertTrue(fileWasRemoved)
end

function testFileRemoveWithSpaceInFileName ()
	local fileName = "file name with space"
	local sandboxFileName = _touchSandbox(fileName)
	local result = ext.fileRemove(fileName)
	local fileWasRemoved = not _isFile(sandboxFileName)
	assertTrue(result)
	assertTrue(fileWasRemoved)
end

function testFileRemoveWithNonExistingFile ()
	local fileName = _getRandomFileName()
	local result = ext.fileRemove(fileName)
	assertTrue(result)
end

function testFileRemoveWithDir ()
	local dirName = _createRandomDir()
	local result = ext.fileRemove(dirName)
	assertFalse(result)
end

-- ------------------------------------------------------------
-- Testes para fileOpen (name, mode)
-- ------------------------------------------------------------

function testFileOpenWithExistingFile ()
	local fileName = _createRandomFile()
	local result = ext.fileOpen(fileName)
	assertNotNil(result)
end

function testFileOpenWithSpaceInFileName ()
	local fileName = "file name with space"
	_touchSandbox(fileName)
	local result = ext.fileOpen(fileName)
	assertNotNil(result)
end

function testFileOpenWithNonExistingFile ()
	local fileName = _getRandomFileName()
	local result = ext.fileOpen(fileName)
	assertNil(result)
end

-- ------------------------------------------------------------
-- Testes para dirGetAbsolutePath (relPath)
-- ------------------------------------------------------------

function testDirGetAbsolutePathWithCurrentDir ()
	local currentDir = _pwd()
	local result = ext.dirGetAbsolutePath(".")
	assertEqual(result, currentDir)
end

function testDirGetAbsolutePathWithSubdir ()
	local subdir = _createRandomDir()
	local result = ext.dirGetAbsolutePath(subdir)
	assertEqual(result, subdir)
end

function testDirGetAbsolutePathWithSpaceInPath ()
	local subdir = "subdir name with space"
	local sandboxSubdir = _mkdirSandbox(subdir)
	local result = ext.dirGetAbsolutePath(sandboxSubdir)
	assertEqual(result, sandboxSubdir)
end

function testDirGetAbsolutePathWithNonExistingDir ()
	local pathFile = _getRandomFileName()
	local result = ext.dirGetAbsolutePath(pathFile)
	assertNil(result)
end

-- ------------------------------------------------------------
-- Testes para dirGetAbsolutePathShell (shell, relPath)
-- ------------------------------------------------------------

function testDirGetAbsolutePathShellWithKsh ()
	local currentDir = _pwd()
	local result = ext.dirGetAbsolutePathShell(ext.SHELL_KSH, ".")
	assertEqual(result, currentDir)
end

function testDirGetAbsolutePathShellWithBash ()
	local currentDir = _pwd()
	local result = ext.dirGetAbsolutePathShell(ext.SHELL_BASH, ".")
	assertEqual(result, currentDir)
end

function testDirGetAbsolutePathShellWithSh ()
	local currentDir = _pwd()
	local result = ext.dirGetAbsolutePathShell(ext.SHELL_SH, ".")
	assertEqual(result, currentDir)
end

function testDirGetAbsolutePathShellWithInvalidShell ()
	local status, err = pcall(ext.dirGetAbsolutePathShell, "non_existing_shell", ".")
	assertFalse(status)
	assertTrue(is_string(err))
end

function testDirGetAbsolutePathShellWithSubdir ()
	local subdir = _createRandomDir()
	local result = ext.dirGetAbsolutePathShell(ext.SHELL_KSH, subdir)
	assertEqual(result, subdir)
end

function testDirGetAbsolutePathShellWithSpaceInPath ()
	local subdir = "subdir name with space"
	local sandboxSubdir = _mkdirSandbox(subdir)
	local result = ext.dirGetAbsolutePathShell(ext.SHELL_KSH, sandboxSubdir)
	assertEqual(result, sandboxSubdir)
end

function testDirGetAbsolutePathShellWithNonExistingDir ()
	local pathFile = _getRandomFileName()
	local result = ext.dirGetAbsolutePathShell(ext.SHELL_KSH, pathFile)
	assertNil(result)
end

-- ------------------------------------------------------------
-- Testes para fileGetAbsolutePath (relPath)
-- ------------------------------------------------------------

function testFileGetAbsolutePathWithExistingFile ()
	local fileName = _createRandomFile()
	local result = ext.fileGetAbsolutePath(fileName)
	assertEqual(result, fileName)
end

function testFileGetAbsolutePathWithNonExistingFile ()
	local currentDir = _pwd()
	local fileName = "name.txt"
	local result = ext.fileGetAbsolutePath("./"..fileName)
	assertEqual(result, currentDir.."/"..fileName)
end

function testFileGetAbsolutePathWithSpaceInPath ()
	local subdir = "dir name with space"
	local sandboxSubdir = _mkdirSandbox(subdir)
	local dirWasCreated = _isDir(sandboxSubdir)
	assertTrue(dirWasCreated)
	local fileName = subdir.."/file name with space.txt"
	local sandboxFileName = _touchSandbox(fileName)
	local fileWasCreated = _isFile(sandboxFileName)
	assertTrue(fileWasCreated)
	local result = ext.fileGetAbsolutePath(sandboxFileName)
	assertEqual(result, sandboxFileName)
end

function testFileGetAbsolutePathWithNonExistingDir ()
	local dirName = _getRandomFileName()
	local fileName = "name.txt"
	local result = ext.fileGetAbsolutePath(dirName.."/"..fileName)
	assertNil(result)
end

-- ------------------------------------------------------------
-- Testes para listOneFile (pattern, caseSensitive, exclude)
-- ------------------------------------------------------------

function testListOneFileWithNoPattern ()
	local rightFile1 = "name1.txt"
	local rightFile2 = "name2.txt"
	local rightFile3 = "name3.txt"
	_touchSandbox(rightFile1)
	_touchSandbox(rightFile2)
	_touchSandbox(rightFile3)
	local result, err = ext.listOneFile()
	assertTrue(result == rightFile1 or result == rightFile2 or result == rightFile3)
	assertNil(err)
end

function testListOneFileWithSpaceInPath ()
	local rightFile1 = "name with space 1.txt"
	local rightFile2 = "name with space 2.txt"
	local rightFile3 = "name with space 3.txt"
	_touchSandbox(rightFile1)
	_touchSandbox(rightFile2)
	_touchSandbox(rightFile3)
	local pattern = "*.txt"
	local result, err = ext.listOneFile(pattern)
	assertTrue(result == rightFile1 or result == rightFile2 or result == rightFile3)
	assertNil(err)
end

function testListOneFileWithSpaceInPattern ()
	local rightFile = "name with space .txt"
	local wrongFile1 = "name_with_no_space_1.txt"
	local wrongFile2 = "name_with_no_space_2.txt"
	_touchSandbox(rightFile)
	_touchSandbox(wrongFile1)
	_touchSandbox(wrongFile2)
	local pattern = "name with*.txt"
	local result, err = ext.listOneFile(pattern)
	assertEqual(result, rightFile)
	assertNil(err)
end

function testListOneFileWithEmptyPattern ()
	local rightFile1 = "name1.txt"
	local rightFile2 = "name2.txt"
	local rightFile3 = "name3.txt"
	_touchSandbox(rightFile1)
	_touchSandbox(rightFile2)
	_touchSandbox(rightFile3)
	local pattern = ""
	local result, err = ext.listOneFile(pattern)
	assertTrue(result == rightFile1 or result == rightFile2 or result == rightFile3)
	assertNil(err)
end

function testListOneFileWithEmptyPatternMatchingFile ()
    local rightFile = "name.txt"
    local wrongFile1 = "name.ext"
    local wrongFile2 = "name.abc"
	_touchSandbox(rightFile)
	_touchSandbox(wrongFile1)
	_touchSandbox(wrongFile2)
	local pattern = "*.txt"
	local result, err = ext.listOneFile(pattern)
	assertEqual(result, rightFile)
	assertNil(err)
end

function testListOneFileWithMultipleMatchingFiles ()
    local rightFile1 = "name1.txt"
    local rightFile2 = "name2.txt"
    local wrongFile = "name.abc"
	_touchSandbox(rightFile1)
	_touchSandbox(rightFile2)
	_touchSandbox(wrongFile)
	local pattern = "*.txt"
	local result, err = ext.listOneFile(pattern)
	assertTrue(result == rightFile1 or result == rightFile2)
	assertNil(err)
end

function testListOneFileWithNoMatchingFiles ()
    local wrongFile1 = "name.txt"
    local wrongFile2 = "name.ext"
    local wrongFile3 = "name.abc"
	_touchSandbox(wrongFile1)
	_touchSandbox(wrongFile2)
	_touchSandbox(wrongFile3)
	local pattern = "*.xxx"
	local result, err = ext.listOneFile(pattern)
	assertEqual(result, "")
	assertNil(err)
end

function testListOneFileMatchingNameStartingWithDot ()
	local rightFile = ".name.txt"
	local wrongFile1 = ".name.ext"
	local wrongFile2 = ".name.abc"
	_touchSandbox(rightFile)
	_touchSandbox(wrongFile1)
	_touchSandbox(wrongFile2)
	local pattern = ".*.txt"
	local result, err = ext.listOneFile(pattern)
	assertEqual(result, rightFile)
	assertNil(err)
end

function testListOneFileIgnoringNameStartingWithDot ()
	local wrongFile1 = ".name.txt"
	local wrongFile2 = ".name.ext"
	local wrongFile3 = ".name.abc"
	_touchSandbox(wrongFile1)
	_touchSandbox(wrongFile2)
	_touchSandbox(wrongFile3)
	local pattern = "*.txt"
	local result, err = ext.listOneFile(pattern)
	assertEqual(result, "")
	assertNil(err)
end

function testListOneFileWithDirInPattern ()
	local dir = _createRandomDir()
	local rightFile = dir.."/name.txt"
	local wrongFile1 = dir.."/name.ext"
	local wrongFile2 = dir.."/name.abc"
	_touch(rightFile)
	_touch(wrongFile1)
	_touch(wrongFile2)
	local pattern = dir.."/*.txt"
	local result, err = ext.listOneFile(pattern)
	assertEqual(result, rightFile)
	assertNil(err)
end

function testListOneFileWithCaseSensitivePattern ()
	local rightFile = "name.Txt"
	local wrongFile1 = "name.txt"
	local wrongFile2 = "name.txT"
	_touchSandbox(rightFile)
	_touchSandbox(wrongFile1)
	_touchSandbox(wrongFile2)
	local pattern = "*.Txt"
	local result, err = ext.listOneFile(pattern, true)
	assertEqual(result, rightFile)
	assertNil(err)
end

function testListOneFileWithExcludePattern ()
	local rightFile = "name.txt"
	local wrongFile1 = "name1.ext"
	local wrongFile2 = "name2.ext"
	_touchSandbox(rightFile)
	_touchSandbox(wrongFile1)
	_touchSandbox(wrongFile2)
	local excludePattern = "*.ext"
	local result, err = ext.listOneFile(excludePattern, false, true)
	assertEqual(result, rightFile)
	assertNil(err)
end

function testListOneFileWithPatternTable () 
	local rightFile1 = "name.txt"
	local rightFile2 = "name.ext" 
	local wrongFile = "name.abc"
	_touchSandbox(rightFile1)
	_touchSandbox(rightFile2)
	_touchSandbox(wrongFile)
	local pattern1 = "*.txt"
	local pattern2 = "*.ext"
	local patterns = { pattern1, pattern2 }
	local result, err = ext.listOneFile(patterns)
	assertTrue(result == rightFile1 or result == rightFile2)
	assertNil(err)
end

function testListOneFileWithEmptyPatternTable ()
	local rightFile1 = "name1.txt"
	local rightFile2 = "name2.txt"
	local rightFile3 = "name3.txt"
	_touchSandbox(rightFile1)
	_touchSandbox(rightFile2)
	_touchSandbox(rightFile3)
	local pattern = {}
	local result, err = ext.listOneFile(pattern)
	assertTrue(result == rightFile1 or result == rightFile2 or result == rightFile3)
	assertNil(err)
end

function testListOneFileWithDirInPatternTable ()
	local dir = _getRandomFileName()
	local pattern1 = dir.."/*.ext"
	local pattern2 = dir.."/*.abc"
	local patterns = { pattern1, pattern2 }
	local result, err = ext.listOneFile(patterns)
	assertNil(result)
	assertTrue(is_string(err))
end

function testListOneFileWithExcludePatternTable ()
	local rightFile = "name.txt"
	local wrongFile1 = "name.abc"
	local wrongFile2 = "name.ext"
	_touchSandbox(rightFile)
	_touchSandbox(wrongFile1)
	_touchSandbox(wrongFile2)
	local excludePattern1 = "*.ext"
	local excludePattern2 = "*.abc"
	local excludePatterns = { excludePattern1, excludePattern2 }
	local result, err = ext.listOneFile(excludePatterns , false, true)
	assertEqual(result, rightFile)
	assertNil(err)
end

-- ------------------------------------------------------------
-- Testes para listFiles  (pattern, caseSensitive, exclude)
-- ------------------------------------------------------------

function testListFilesWithNoPattern ()
	local rightFile1 = _createRandomFile()
	local rightFile2 = _createRandomFile()
	local rightFile3 = _createRandomFile()
	local result, err = ext.listFiles()
	local sortedResult = _split(result)
	local fileList = { rightFile1 , rightFile2, rightFile3 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListFilesWithEmptyPattern ()
	local rightFile1 = _createRandomFile()
	local rightFile2 = _createRandomFile()
	local rightFile3 = _createRandomFile()
	local pattern = ""
	local result, err = ext.listFiles(pattern)
	local sortedResult = _split(result)
	local fileList = { rightFile1 , rightFile2, rightFile3 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListFilesWithSpaceInPath ()
	local rightFile1 = "name with space 1.txt"
	local rightFile2 = "name with space 2.txt"
	local rightFile3 = "name with space 3.txt"
	_touchSandbox(rightFile1)
	_touchSandbox(rightFile2)
	_touchSandbox(rightFile3)
	local pattern = "*.txt"
	local result, err = ext.listFiles(pattern)
	local sortedResult = _split(result)
	local fileList = { rightFile1 , rightFile2, rightFile3 }
	assertTableEqual(sortedResult, fileList)
	assertNotNil(result)
	assertNil(err)
end

function testListFilesWithSpaceInPattern ()
	local rightFile = "name with space .txt"
	local wrongFile1 = "name_with_no_space_1.txt"
	local wrongFile2 = "name_with_no_space_2.txt"
	_touchSandbox(rightFile)
	_touchSandbox(wrongFile1)
	_touchSandbox(wrongFile2)
	local pattern = "name with*.txt"
	local result, err = ext.listFiles(pattern)
	assertEqual(result, rightFile.."\n")
	assertNil(err)
end

function testListFilesWithSingleMatchingFile ()
    local rightFile = "name.txt"
    local wrongFile1 = "name.ext"
    local wrongFile2 = "name.abc"
	_touchSandbox(rightFile)
	_touchSandbox(wrongFile1)
	_touchSandbox(wrongFile2)
	local pattern = "*.txt"
	local result, err = ext.listFiles(pattern)
	assertEqual(result, rightFile.."\n")
	assertNil(err)
end

function testListFilesWithMultipleMatchingFiles ()
    local rightFile1 = "name1.txt"
    local rightFile2 = "name2.txt"
    local wrongFile = "name.abc"
	_touchSandbox(rightFile1)
	_touchSandbox(rightFile2)
	_touchSandbox(wrongFile)
	local pattern = "*.txt"
	local result, err = ext.listFiles(pattern)
	local sortedResult = _split(result)
	local fileList = { rightFile1 , rightFile2 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListFilesWithNoMatchingFiles ()
    local wrongFile1 = "name.txt"
    local wrongFile2 = "name.ext"
    local wrongFile3 = "name.abc"
	_touchSandbox(wrongFile1)
	_touchSandbox(wrongFile2)
	_touchSandbox(wrongFile3)
	local pattern = "*.xxx"
	local result, err = ext.listFiles(pattern)
	assertEqual(result, "")
	assertNil(err)
end

function testListFilesMatchingNameStartingWithDot ()
     local wrongFile1 = "name1.txt"
     local wrongFile2 = "name2.txt"
     local rightFile = ".name_with_dot.txt"
	_touchSandbox(wrongFile1)
	_touchSandbox(wrongFile2)
	_touchSandbox(rightFile)
	local pattern = ".*.txt"
	local result, err = ext.listFiles(pattern)
	assertEqual(result, rightFile.."\n")
	assertNil(err)
end

function testListFilesIgnoringNameStartingWithDot ()
     local rightFile1 = "name1.txt"
     local rightFile2 = "name2.txt"
     local wrongFile = ".name_with_dot.txt"
	_touchSandbox(rightFile1)
	_touchSandbox(rightFile2)
	_touchSandbox(wrongFile)
	local pattern = "*.txt"
	local result, err = ext.listFiles(pattern)
	local sortedResult = _split(result)
	local fileList = { rightFile1, rightFile2 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListFilesWithDirInPattern ()
	local dir = _createRandomDir()
	local rightFile1 = dir.."/name1.txt"
	local rightFile2 = dir.."/name2.txt"
	local wrongFile = dir.."/name.abc"
	_touch(rightFile1)
	_touch(rightFile2)
	_touch(wrongFile)
	local pattern = dir.."/*.txt"
	local result, err = ext.listFiles(pattern)
	local sortedResult = _split(result)
	local fileList = { rightFile1, rightFile2 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListFilesWithCaseSensitivePattern ()
    local rightFile1 = "name1.Txt"
    local rightFile2 = "name2.Txt"
    local wrongFile = "name3.txt"
	_touchSandbox(rightFile1)
	_touchSandbox(rightFile2)
	_touchSandbox(wrongFile)
	local pattern = "*.Txt"
	local result, err = ext.listFiles(pattern, true)
	local sortedResult = _split(result)
	local fileList = { rightFile1 , rightFile2 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListFilesWithExcludePattern ()
	local rightFile1 = "name1.ext"
	local rightFile2 = "name2.ext"
	local wrongFile = "name.txt"
	_touchSandbox(rightFile1)
	_touchSandbox(rightFile2)
	_touchSandbox(wrongFile)
	local excludePattern = "*.txt"
	local result, err = ext.listFiles(excludePattern, false, true)
	local sortedResult = _split(result)
	local fileList = { rightFile1 , rightFile2 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListFilesWithPatternTable () 
	local rightFile1 = "name.ext"
	local rightFile2 = "name.txt" 
	local wrongFile = "name.abc"
	_touchSandbox(rightFile1)
	_touchSandbox(rightFile2)
	_touchSandbox(wrongFile)
	local pattern1 = "*.txt"
	local pattern2 = "*.ext"
	local patterns = { pattern1, pattern2 }
	local result, err = ext.listFiles(patterns)
	local sortedResult = _split(result)
	local fileList = { rightFile1 , rightFile2 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListFilesWithEmptyPatternTable ()
	local rightFile1 = _createRandomFile()
	local rightFile2 = _createRandomFile()
	local rightFile3 = _createRandomFile()
	local pattern = {}
	local result, err = ext.listFiles(pattern)
	local sortedResult = _split(result)
	local fileList = { rightFile1 , rightFile2, rightFile3 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListFilesWithDirInPatternTable ()
	local dir = _getRandomFileName()
	local pattern1 = dir.."/*.ext"
	local pattern2 = dir.."/*.abc"
	local patterns = { pattern1, pattern2 }
	local result, err = ext.listFiles(patterns)
	assertNil(result)
	assertTrue(is_string(err))
end

function testListFilesWithExcludePatternTable ()
	local rightFile = "name.txt"
	local wrongFile1 = "name.abc"
	local wrongFile2 = "name.ext"
	_touchSandbox(rightFile)
	_touchSandbox(wrongFile1)
	_touchSandbox(wrongFile2)
	local excludePattern1 = "*.ext"
	local excludePattern2 = "*.abc"
	local excludePatterns = { excludePattern1, excludePattern2 }
	local result, err = ext.listFiles(excludePatterns, false, true)
	assertEqual(result, rightFile.."\n")
	assertNil(err)
end

-- ------------------------------------------------------------
-- Testes para listDirs  (pattern, caseSensitive, exclude)
-- ------------------------------------------------------------

function testListDirsWithNoPattern ()
    local rightDir1 = _createRandomDir()
    local rightDir2 = _createRandomDir()
    local rightDir3 = _createRandomDir()
	local result, err = ext.listDirs()
	local sortedResult = _split(result)
	local fileList = { rightDir1, rightDir2, rightDir3 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListDirsWithEmptyPattern ()
	local rightDir1 = _createRandomDir()
	local rightDir2 = _createRandomDir()
	local rightDir3 = _createRandomDir()
	local pattern = ""
	local result, err = ext.listDirs(pattern)
	local sortedResult = _split(result)
	local fileList = { rightDir1, rightDir2, rightDir3 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListDirsWithSpaceInPath ()
	local rightDir1 = "dir name with space 1"
	local rightDir2 = "dir name with space 2"
	local rightDir3 = "dir name with space 3"
	_mkdirSandbox(rightDir1)
	_mkdirSandbox(rightDir2)
	_mkdirSandbox(rightDir3)
	local pattern = "dir*"
	local result, err = ext.listDirs(pattern)
	local sortedResult = _split(result)
	local fileList = { rightDir1, rightDir2, rightDir3 }
	assertTableEqual(sortedResult, fileList)
	assertNotNil(result)
	assertNil(err)
end

function testListDirsWithSpaceInPattern ()
	local rightDir = "dir name with space 1"
	local wrongDir1 = "dir_name_ with_no_space_ 2"
	local wrongDir2 = "dir_name_with_no_space_3"
	_mkdirSandbox(rightDir)
	_mkdirSandbox(wrongDir1)
	_mkdirSandbox(wrongDir2)
	local pattern = "dir name*"
	local result, err = ext.listDirs(pattern)
	assertEqual(result, rightDir.."\n")
	assertNil(err)
end


function testListDirsWithSingleMatchingFile ()
    local rightDir = "dirname1"
    local wrongDir1 = "wrong_dirname2"
    local wrongDir2 = "wrong_dirname3"
	_mkdirSandbox(rightDir)
	_mkdirSandbox(wrongDir1)
	_mkdirSandbox(wrongDir2)
	local pattern = "dirname*"
	local result, err = ext.listDirs(pattern)
	assertEqual(result, rightDir.."\n")
	assertNil(err)
end

function testListDirsWithMultipleMatchingFiles ()
    local rightDir1 = "dirname1"
    local rightDir2 = "dirname2"
    local wrongDir = "wrong_dirname3"
	_mkdirSandbox(rightDir1)
	_mkdirSandbox(rightDir2)
	_mkdirSandbox(wrongDir)
	local pattern = "dirname*"
	local result, err = ext.listDirs(pattern)
	local sortedResult = _split(result)
	local fileList = { rightDir1, rightDir2 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end


function testListDirsWithNoMatchingFiles ()
	local wrongDir1 = "wrong_dirname1"
	local wrongDir2 = "wrong_dirname2"
	local wrongDir3 = "wrong_dirname3"
	_mkdirSandbox(wrongDir1)
	_mkdirSandbox(wrongDir2)
	_mkdirSandbox(wrongDir3)
	local pattern = "dirname*"
	local result, err = ext.listDirs(pattern)
	assertEqual(result, "")
	assertNil(err)
end

function testListDirsIgnoringNameStartingWithDot ()
	local rightDir1 = "dirname1"
	local rightDir2 = "dirname2"
	local wrongDir = ".dirname3_with_dot"
	_mkdirSandbox(rightDir1)
	_mkdirSandbox(rightDir2)
	_mkdirSandbox(wrongDir)
	local pattern = "dirname*"
	local result, err = ext.listDirs(pattern)
	local sortedResult = _split(result)
	local fileList = { rightDir1 , rightDir2 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListDirsMatchingNameStartingWithDot ()
	local rightDir1 = ".dirname1"
	local rightDir2 = ".dirname2"
	local wrongDir = "dirname3"
	_mkdirSandbox(rightDir1)
	_mkdirSandbox(rightDir2)
	_mkdirSandbox(wrongDir)
	local pattern = ".dirname*"
	local result, err = ext.listDirs(pattern)
	local sortedResult = _split(result)
	local fileList = { rightDir1 , rightDir2 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListDirsWithDirInPattern ()
	local dir = _createRandomDir()
	local rightDir1 = dir.."/dirname1"
	local rightDir2 = dir.."/dirname2"
	local wrongDir = dir.."/wrong_dirname3"
	_mkdir(rightDir1)
	_mkdir(rightDir2)
	_mkdir(wrongDir)
	local pattern = dir.."/dirname*"
	local result, err = ext.listDirs(pattern)
	local sortedResult = _split(result)
	local fileList = { rightDir1, rightDir2 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListDirsWithCaseSensitivePattern ()
    local rightDir1 = "dirName1"
    local rightDir2 = "dirName2"
    local wrongDir = "dirname3"
	_mkdirSandbox(rightDir1)
	_mkdirSandbox(rightDir2)
	_mkdirSandbox(wrongDir)
	local pattern = "dirName*"
	local result, err = ext.listDirs(pattern, true)
	local sortedResult = _split(result)
	local fileList = { rightDir1, rightDir2 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListDirsWithExcludePattern ()
    local rightDir1 = "dirname1"
    local rightDir2 = "dirname2"
    local wrongDir = "wrong_dirname3"
	_mkdirSandbox(rightDir1)
	_mkdirSandbox(rightDir2)
	_mkdirSandbox(wrongDir)
	local excludePattern = "wrong_*"
	local result, err = ext.listDirs(excludePattern, false, true)
	local sortedResult = _split(result)
	local fileList = { rightDir1, rightDir2 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListDirsWithPatternTable ()
    local rightDir1 = "dirname1_lock"
    local rightDir2 = "dirname2_done"
    local wrongDir = "dirname3"
	_mkdirSandbox(rightDir1)
	_mkdirSandbox(rightDir2)
	_mkdirSandbox(wrongDir)
	local pattern1 = "*_lock"
	local pattern2 = "*_done"
	local patterns =  { pattern1, pattern2 }
	local result, err = ext.listDirs(patterns)
	local sortedResult = _split(result)
	local fileList = { rightDir1, rightDir2 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListDirsWithEmptyPatternTable ()
    local rightDir1 = "dirname1"
    local rightDir2 = "dirname2"
    local rightDir3 = "dirname3"
	_mkdirSandbox(rightDir1)
	_mkdirSandbox(rightDir2)
	_mkdirSandbox(rightDir3)
	local pattern = {}
	local result, err = ext.listDirs(pattern)
	local sortedResult = _split(result)
	local fileList = { rightDir1, rightDir2, rightDir3 }
	assertTableEqual(sortedResult, fileList)
	assertNil(err)
end

function testListDirsWithDirInPatternTable ()
	local dir = _getRandomFileName()
	local pattern1 = dir.."/*_lock"
	local pattern2 = dir.."/*_done"
	local patterns = { pattern1, pattern2 }
	local result, err = ext.listDirs(patterns)
	assertNil(result)
	assertTrue(is_string(err))
end

function testListDirsWithExcludingPatternTable ()
    local wrongDir1 = "dirname1_lock"
    local wrongDir2 = "dirname2_done"
    local rightDir = "dirname3"
	_mkdirSandbox(wrongDir1)
	_mkdirSandbox(wrongDir2)
	_mkdirSandbox(rightDir)
	local excludePattern1 = "*_lock"
	local excludePattern2 = "*_done"
	local excludePatterns = { excludePattern1, excludePattern2 }
	local result, err = ext.listDirs( excludePatterns , false, true )
	assertEqual(result, rightDir.."\n")
	assertNil(err)
end

-- ------------------------------------------------------------
-- Testes para emptyFile (name)
-- ------------------------------------------------------------

function testEmptyFileWithNonExistingFile ()
	local fileName = _getRandomFileName()
	local fileDidNotExist = not _isFile(fileName)
	ext.emptyFile(fileName)
	local fileExists = _isFile(fileName)
	local content = _readFile(fileName)
	assertTrue(fileDidNotExist)
	assertTrue(fileExists)
	assertEqual(content, "")
end

function testEmptyFileWithSpaceInFileName ()
	local fileName = "file name with space"
	local sandboxFileName = _nameInSandbox(fileName)
	local fileDidNotExist = not _isFile(sandboxFileName)
	ext.emptyFile(fileName)
	local fileExists = _isFile(sandboxFileName)
	local content = _readFile(sandboxFileName)
	assertTrue(fileDidNotExist)
	assertTrue(fileExists)
	assertEqual(content, "")
end

function testEmptyFileWithExistingFile ()
	local fileName = _createRandomFile()
	local content = "line1 line1 line1\n"
	_writeFile(fileName, content)
	local fileDidExist = _isFile(fileName)
	ext.emptyFile(fileName)
	local fileExists = _isFile(fileName)
	local content = _readFile(fileName)
	assertTrue(fileDidExist)
	assertTrue(fileExists)
	assertEqual(content, "")
end

-- ------------------------------------------------------------
-- Testes para setWinTitle (name)
-- ------------------------------------------------------------

function testSetWinTitle ()
	local status, err = pcall(ext.setWinTitle, "TITLE")
	assertTrue(status)
	assertNil(err)
end

function testSetWinTitleWithNil ()
	local status, err = pcall(ext.setWinTitle, nil)
	assertTrue(status)
	assertNil(err)
end

-- ------------------------------------------------------------
-- Testes para fileReplaceTexts (fileIn, fileOut, tableArg)
-- ------------------------------------------------------------

function testFileReplaceTextsWithSinglePattern ()
	local fileInName = _createRandomFile()
	local fileOutName = _createRandomFile()
	local content = "line1 _REPLACE_ line1\n_REPLACE_ line2 line2\nline3 line3 _REPLACE_\n"
	_writeFile(fileInName, content)
	local table = { "_REPLACE_", "_REPLACED_"}
	ext.fileReplaceTexts(fileInName, fileOutName, table)	
	local result = _readFile(fileOutName)
	assertEqual(result, "line1 _REPLACED_ line1\n_REPLACED_ line2 line2\nline3 line3 _REPLACED_\n")
end

function testFileReplaceTextsWithSpaceInFileName ()
	local fileInName = "input file name with space" 
	local fileOutName = "output file name with space"
	local sandboxFileInName = _touchSandbox(fileInName)
	local sandboxFileOutName = _touchSandbox(fileOutName)
	local content = "line1 _REPLACE_ line1\n_REPLACE_ line2 line2\nline3 line3 _REPLACE_\n"
	_writeFile(sandboxFileInName, content)
	local table = { "_REPLACE_", "_REPLACED_"}
	ext.fileReplaceTexts(fileInName, fileOutName, table)	
	local result = _readFile(sandboxFileOutName)
	assertEqual(result, "line1 _REPLACED_ line1\n_REPLACED_ line2 line2\nline3 line3 _REPLACED_\n")
end

function testFileReplaceTextsWithMultiplePatterns ()
	local fileInName = _createRandomFile()
	local fileOutName = _createRandomFile()
	local content = "line1 _REPLACE1_ line1\n_REPLACE2_ line2 line2\nline3 line3 _REPLACE3_\n"
	_writeFile(fileInName, content)
	local table = { "_REPLACE1_", "_REPLACED1_", "_REPLACE2_", "_REPLACED2_", "_REPLACE3_", "_REPLACED3_"}
	ext.fileReplaceTexts(fileInName, fileOutName, table)
	local result = _readFile(fileOutName)
	assertEqual(result, "line1 _REPLACED1_ line1\n_REPLACED2_ line2 line2\nline3 line3 _REPLACED3_\n")
end

function testFileReplaceTextsWithNoPatterns ()
	local fileInName = _createRandomFile()
	local fileOutName = _createRandomFile()
	local content = "line1 _REPLACE1_ line1\n_REPLACE2_ line2 line2\nline3 line3 _REPLACE3_\n"
	_writeFile(fileInName, content)
	local table = { }
	ext.fileReplaceTexts(fileInName, fileOutName, table)
	local result = _readFile(fileOutName)
	assertEqual(result, content)
end

function testFileReplaceTextsWithNothingToReplace ()
	local fileInName = _createRandomFile()
	local fileOutName = _createRandomFile()
	local content = "line1 line1 line1\nline2 line2 line2\nline3 line3 line3\n"
	_writeFile(fileInName, content)
	local table = { "_REPLACE_", "_REPLACED_"}
	ext.fileReplaceTexts(fileInName, fileOutName, table)
	local result = _readFile(fileOutName)
	assertEqual(result, content)
end

-- ------------------------------------------------------------
-- Testes para fileReplaceText (fileIn, fileOut, search, replace)
-- ------------------------------------------------------------

function testFileReplaceTextWithMatchingTexts ()
	local fileInName = _createRandomFile()
	local fileOutName = _createRandomFile()
	local content = "line1 _REPLACE_ line1\n_REPLACE_ line2 line2\nline3 line3 _REPLACE_\n"
	_writeFile(fileInName, content)
	ext.fileReplaceText(fileInName, fileOutName, "_REPLACE_", "_REPLACED_")
	local result = _readFile(fileOutName)
	assertEqual(result, "line1 _REPLACED_ line1\n_REPLACED_ line2 line2\nline3 line3 _REPLACED_\n")
end

function testFileReplaceTextWithSpaceInFileName ()
	local fileInName = "input file name with space" 
	local fileOutName = "output file name with space"
	local sandboxFileInName = _touchSandbox(fileInName)
	local sandboxFileOutName = _touchSandbox(fileOutName)
	local content = "line1 _REPLACE_ line1\n_REPLACE_ line2 line2\nline3 line3 _REPLACE_\n"
	_writeFile(sandboxFileInName, content)
	ext.fileReplaceText(fileInName, fileOutName, "_REPLACE_", "_REPLACED_")
	local result = _readFile(sandboxFileOutName)
	assertEqual(result, "line1 _REPLACED_ line1\n_REPLACED_ line2 line2\nline3 line3 _REPLACED_\n")
end

function testFileReplaceTextWithNoMatchingText ()
	local fileInName = _createRandomFile()
	local fileOutName = _createRandomFile()
	local content = "line1 line1 line1\nline2 line2 line2\nline3 line3 line3\n"
	_writeFile(fileInName, content)
	ext.fileReplaceText(fileInName, fileOutName, "_REPLACE_", "_REPLACED_")
	local result = _readFile(fileOutName)
	assertEqual(result, content)
end

-- ------------------------------------------------------------
-- Testes para execCmd (shell, cmd, logFile, showOutput)
-- ------------------------------------------------------------

function testExecCmdWithBashShell ()
	local logFileName = _getRandomFileName()
	local cmd = "echo OUT" 
	local result = ext.execCmd(ext.SHELL_BASH, cmd, logFileName)
	local logFileWasCreated = _isFile(logFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(logFileName)
	assertTrue(result)
	assertEqual(content, "OUT\n")
end

function testExecCmdWithKshShell ()
	local logFileName = _getRandomFileName()
	local cmd = "echo OUT" 
	local result = ext.execCmd(ext.SHELL_KSH, cmd, logFileName)
	local logFileWasCreated = _isFile(logFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(logFileName)
	assertTrue(result)
	assertEqual(content, "OUT\n")
end

function testExecCmdWithShShell ()
	local logFileName = _getRandomFileName()
	local cmd = "echo OUT" 
	local result = ext.execCmd(ext.SHELL_SH, cmd, logFileName)
	local logFileWasCreated = _isFile(logFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(logFileName)
	assertTrue(result)
	assertEqual(content, "OUT\n")
end

function testExecCmdWithInvalidShell ()
	local logFileName = _getRandomFileName()
	local cmd = "echo OUT" 
	local status, err = pcall(ext.execCmd, "non_existing_shell", cmd, logFileName)
	local logFileWasCreated = _isFile(logFileName)
	assertFalse(logFileWasCreated)
	assertFalse(status)
	assertTrue(is_string(err))
end

function testExecCmdWithInvalidCmd ()
	local logFileName = _getRandomFileName()
	local cmd = "./non_existing_command" 
	local result = ext.execCmd(ext.SHELL_BASH, cmd, logFileName)
	local logFileWasCreated = _isFile(logFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(logFileName)
	assertFalse(result)
	assertNotEqual(content, "")
end

function testExecCmdWithSpaceInLogFileName ()
	local logFileName = "log file name with space.log"
	local sandboxFileName = _nameInSandbox(logFileName)
	local cmd = "echo OUT" 
	local result = ext.execCmd(ext.SHELL_BASH, cmd, logFileName)
	local logFileWasCreated = _isFile(sandboxFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(sandboxFileName)
	assertTrue(result)
	assertEqual(content, "OUT\n")
end

function testExecCmdWithOutput ()
	local outFileName = _getRandomFileName()
	local cmd = "echo OUT > "..outFileName 
	local result = ext.execCmd(ext.SHELL_BASH, cmd, nil, true)
	local outFileWasCreated = _isFile(outFileName)
	assertTrue(outFileWasCreated)
	local content = _readFile(outFileName)
	assertTrue(result)
	assertEqual(content, "OUT\n")
end

function testExecCmdWithNoOutput ()
	local outFileName = _getRandomFileName()
	local cmd = "echo OUT > "..outFileName 
	local result = ext.execCmd(ext.SHELL_BASH, cmd, nil, false)
	local outFileWasCreated = _isFile(outFileName)
	assertTrue(outFileWasCreated)
	local content = _readFile(outFileName)
	assertTrue(result)
	assertEqual(content, "")
end


-- ------------------------------------------------------------
-- Testes para execCmdWithParams (shell, cmd, logFile, showOutput, ...)
-- ------------------------------------------------------------

function testExecCmdWithParamsWithBashShell ()
	local logFileName = _getRandomFileName()
	local cmd = "cat" 
	local result = ext.execCmdWithParams(ext.SHELL_BASH, cmd, logFileName, false, "OUT")
	local logFileWasCreated = _isFile(logFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(logFileName)
	assertTrue(result)
	assertEqual(content, "OUT\n")
end

function testExecCmdWithParamsWithKshShell ()
	local logFileName = _getRandomFileName()
	local cmd = "cat" 
	local result = ext.execCmdWithParams(ext.SHELL_KSH, cmd, logFileName, false, "OUT")
	local logFileWasCreated = _isFile(logFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(logFileName)
	assertTrue(result)
	assertEqual(content, "OUT\n")
end

function testExecCmdWithParamsWithShShell ()
	local logFileName = _getRandomFileName()
	local cmd = "cat" 
	local result = ext.execCmdWithParams(ext.SHELL_SH, cmd, logFileName, false, "OUT")
	local logFileWasCreated = _isFile(logFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(logFileName)
	assertTrue(result)
	assertEqual(content, "OUT\n")
end

function testExecCmdWithParamsWithInvalidShell ()
	local logFileName = _getRandomFileName()
	local cmd = "cat" 
	local status, err = pcall(ext.execCmdWithParams, "non_existing_shell", cmd, logFileName, false, "OUT")
	local logFileWasCreated = _isFile(logFileName)
	assertFalse(logFileWasCreated)
	assertFalse(status)
	assertTrue(is_string(err))
end

function testExecCmdWithParamsWithInvalidCmd ()
	local logFileName = _getRandomFileName()
	local cmd = "./non_existing_command" 
	local result = ext.execCmdWithParams(ext.SHELL_BASH, cmd, logFileName, false, 100, "OUT")
	local logFileWasCreated = _isFile(logFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(logFileName)
	assertFalse(result)
	assertNotEqual(content, "")
end

function testExecCmdWithParamsWithSpaceInLogFileName ()
	local logFileName = "log file name with space.log"
	local sandboxFileName = _nameInSandbox(logFileName)
	local cmd = "cat" 
	local result = ext.execCmdWithParams(ext.SHELL_BASH, cmd, logFileName, false, "OUT")
	local logFileWasCreated = _isFile(sandboxFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(sandboxFileName)
	assertTrue(result)
	assertEqual(content, "OUT\n")
end

function testExecCmdWithParamsWithOutuput ()
	local outFileName = _getRandomFileName()
	local cmd = "cat > "..outFileName
	local result = ext.execCmdWithParams(ext.SHELL_BASH, cmd, nil, true, "OUT")
	local outFileWasCreated = _isFile(outFileName)
	assertTrue(outFileWasCreated)
	local content = _readFile(outFileName)
	assertTrue(result)
	assertEqual(content, "OUT\n")
end

function testExecCmdWithParamsWithNoOutuput ()
	local outFileName = _getRandomFileName()
	local cmd = "cat > "..outFileName
	local result = ext.execCmdWithParams(ext.SHELL_BASH, cmd, nil, false, "OUT")
	local outFileWasCreated = _isFile(outFileName)
	assertTrue(outFileWasCreated)
	local content = _readFile(outFileName)
	assertTrue(result)
	assertEqual(content, "")
end

-- ------------------------------------------------------------
-- Testes para execCmdWithEnvVarParams (shell, envVar, cmd, logFile, showOutput,...)
-- ------------------------------------------------------------

function testExecCmdWithEnvVarParamsWithBashShell ()
	local logFileName = _createRandomFile()
	local envVars = { ["TEST_ENV_VAR1"] = "VAR1", ["TEST_ENV_VAR2"] = "VAR2" }
	local cmd = "(echo \\$TEST_ENV_VAR1; echo \\$TEST_ENV_VAR2)"
	local result = ext.execCmdWithEnvVarParams(ext.SHELL_BASH, envVars, cmd, logFileName)
	local logFileWasCreated = _isFile(logFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(logFileName)
	assertTrue(result)
	assertEqual(content, "VAR1\nVAR2\n")
end

function testExecCmdWithEnvVarParamsWithKshShell ()
	local logFileName = _createRandomFile()
	local envVars = { ["TEST_ENV_VAR1"] = "VAR1", ["TEST_ENV_VAR2"] = "VAR2" }
	local cmd = "(echo \\$TEST_ENV_VAR1; echo \\$TEST_ENV_VAR2)"
	local result = ext.execCmdWithEnvVarParams(ext.SHELL_KSH, envVars, cmd, logFileName)
	local logFileWasCreated = _isFile(logFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(logFileName)
	assertTrue(result)
	assertEqual(content, "VAR1\nVAR2\n")
end

function testExecCmdWithEnvVarParamsWithShShell ()
	local logFileName = _createRandomFile()
	local envVars = { ["TEST_ENV_VAR1"] = "VAR1", ["TEST_ENV_VAR2"] = "VAR2" }
	local cmd = "(echo \\$TEST_ENV_VAR1; echo \\$TEST_ENV_VAR2)"
	local result = ext.execCmdWithEnvVarParams(ext.SHELL_SH, envVars, cmd, logFileName)
	local logFileWasCreated = _isFile(logFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(logFileName)
	assertTrue(result)
	assertEqual(content, "VAR1\nVAR2\n")
end

function testExecCmdWithEnvVarParamsWithInvalidShell ()
	local logFileName = _getRandomFileName()
	local envVars = { ["TEST_ENV_VAR1"] = "VAR1", ["TEST_ENV_VAR2"] = "VAR2" }
	local cmd = "(echo \\$TEST_ENV_VAR1; echo \\$TEST_ENV_VAR2)"
	local status, err = pcall(ext.execCmdWithEnvVarParams, "non_existing_shell", envVars, cmd, logFileName)
	local logFileWasCreated = _isFile(logFileName)
	assertFalse(status)
	assertTrue(is_string(err))
	assertFalse(logFileWasCreated)
end

function testExecCmdWithEnvVarParamsWithInvalidCmd ()
	local logFileName = _createRandomFile()
	local envVars = { ["TEST_ENV_VAR1"] = "VAR1", ["TEST_ENV_VAR2"] = "VAR2" }
	local cmd = "./non_existing_command" 
	local result = ext.execCmdWithEnvVarParams(ext.SHELL_BASH, envVars, cmd, logFileName)
	local logFileWasCreated = _isFile(logFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(logFileName)
	assertFalse(result)
	assertNotEqual(content, "")
end

function testExecCmdWithEnvVarParamsWithNoEnvVars ()
	local logFileName = _createRandomFile()
	local envVars = {}
	local cmd = "echo \\$TEST_NOT_DEFINED_ENV_VAR"
	local result = ext.execCmdWithEnvVarParams(ext.SHELL_BASH, envVars, cmd, logFileName)
	local logFileWasCreated = _isFile(logFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(logFileName)
	assertTrue(result)
	assertEqual(content, "\n")
end

function testExecCmdWithEnvVarParamsWithSpaceInLogFileName ()
	local logFileName = "log file name with space.log"
	local sandboxFileName = _nameInSandbox(logFileName)
	local envVars = { ["TEST_ENV_VAR1"] = "VAR1", ["TEST_ENV_VAR2"] = "VAR2" }
	local cmd = "(echo \\$TEST_ENV_VAR1; echo \\$TEST_ENV_VAR2)"
	local result = ext.execCmdWithEnvVarParams(ext.SHELL_BASH, envVars, cmd, logFileName)
	local logFileWasCreated = _isFile(sandboxFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(sandboxFileName)
	assertTrue(result)
	assertEqual(content, "VAR1\nVAR2\n")
end

function testExecCmdWithEnvVarParamsWithOutput ()
	local outFileName = _createRandomFile()
	local envVars = { ["TEST_ENV_VAR1"] = "VAR1", ["TEST_ENV_VAR2"] = "VAR2" }
	local cmd = "(echo \\$TEST_ENV_VAR1; echo \\$TEST_ENV_VAR2) > "..outFileName
	local result = ext.execCmdWithEnvVarParams(ext.SHELL_BASH, envVars, cmd, nil, true)
	local outFileWasCreated = _isFile(outFileName)
	assertTrue(outFileWasCreated)
	local content = _readFile(outFileName)
	assertTrue(result)
	assertEqual(content, "VAR1\nVAR2\n")
end

function testExecCmdWithEnvVarParamsWithNoOutput ()
	local outFileName = _createRandomFile()
	local envVars = { ["TEST_ENV_VAR1"] = "VAR1", ["TEST_ENV_VAR2"] = "VAR2" }
	local cmd = "(echo \\$TEST_ENV_VAR1; echo \\$TEST_ENV_VAR2) > "..outFileName
	local result = ext.execCmdWithEnvVarParams(ext.SHELL_BASH, envVars, cmd, nil, false)
	local outFileWasCreated = _isFile(outFileName)
	assertTrue(outFileWasCreated)
	local content = _readFile(outFileName)
	assertTrue(result)
	assertEqual(content, "")
end
-- ------------------------------------------------------------
-- Testes para execCmdLine (shell, cmd, logFile, showOutput...)
-- ------------------------------------------------------------

function testExecCmdLineWithBashShell ()
	local logFileName = _createRandomFile()
	local cmd = "echo"
	local result = ext.execCmdLine(ext.SHELL_BASH, cmd, logFileName, false, "OUT")
	local logFileWasCreated = _isFile(logFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(logFileName)
	assertTrue(result)
	assertEqual(content, "OUT\n")
end

function testExecCmdLineWithKhShell ()
	local logFileName = _createRandomFile()
	local cmd = "echo"
	local result = ext.execCmdLine(ext.SHELL_KSH, cmd, logFileName, false, "OUT")
	local logFileWasCreated = _isFile(logFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(logFileName)
	assertTrue(result)
	assertEqual(content, "OUT\n")
end

function testExecCmdLineWithShShell ()
	local logFileName = _createRandomFile()
	local cmd = "echo"
	local result = ext.execCmdLine(ext.SHELL_KSH, cmd, logFileName, false, "OUT")
	local logFileWasCreated = _isFile(logFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(logFileName)
	assertTrue(result)
	assertEqual(content, "OUT\n")
end

function testExecCmdLineWithInvalidShell ()
	local logFileName = _getRandomFileName()
	local cmd = "echo" 
	local status, err = pcall(ext.execCmdLine, "non_existing_shell", cmd, logFileName, false, "OUT")
	local logFileWasCreated = _isFile(logFileName)
	assertFalse(status)
	assertTrue(is_string(err))
	assertFalse(logFileWasCreated)
end

function testExecCmdLineWithInvalidCmd ()
	local logFileName = _createRandomFile()
	local cmd = "./non_existing_command" 
	local result = ext.execCmdLine(ext.SHELL_BASH, cmd, logFileName, false, "OUT")
	local logFileWasCreated = _isFile(logFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(logFileName)
	assertFalse(result)
	assertNotEqual(content, "")
end

function testExecCmdLineWithSpaceInLogFileName ()
	local logFileName = "log file name with space.log"
	local sandboxFileName = _nameInSandbox(logFileName)
	local cmd = "echo"
	local result = ext.execCmdLine(ext.SHELL_BASH, cmd, logFileName, false, "OUT")
	local logFileWasCreated = _isFile(sandboxFileName)
	assertTrue(logFileWasCreated)
	local content = _readFile(sandboxFileName)
	assertTrue(result)
	assertEqual(content, "OUT\n")
end

function testExecCmdLineWithOutput ()
	local outFileName = _createRandomFile()
	local cmd = "echo > "..outFileName
	local result = ext.execCmdLine(ext.SHELL_BASH, cmd, nil, true, "OUT")
	local outFileWasCreated = _isFile(outFileName)
	assertTrue(outFileWasCreated)
	local content = _readFile(outFileName)
	assertTrue(result)
	assertEqual(content, "OUT\n")
end

function testExecCmdLineWithNoOutput ()
	local outFileName = _createRandomFile()
	local cmd = "echo > "..outFileName
	local result = ext.execCmdLine(ext.SHELL_BASH, cmd, nil, false, "OUT")
	local outFileWasCreated = _isFile(outFileName)
	assertTrue(outFileWasCreated)
	local content = _readFile(outFileName)
	assertTrue(result)
	assertEqual(content, "")
end

-- ------------------------------------------------------------
-- Testes para getCommonPath (paths)
-- ------------------------------------------------------------

function testGetCommonPathFromSinglePath ()
	local path = { "/aaa/bbb/ccc" }
	local commonInPath, fileTable = ext.getCommonPath(path)
	assertEqual(commonInPath, "/aaa/bbb/") -- No caso de 1 path, a parte em comum retorna com "/" no final
	assertTableEqual(fileTable, { "ccc" })
end

function testGetCommonPathFromMultipleMatchingPaths ()
	local paths = { "/aaa/bbb/ccc", "/aaa/bbb/ddd", "/aaa/bbb/eee/fff" }
	local commonInPath, fileTable = ext.getCommonPath(paths)
	assertEqual(commonInPath, "/aaa/bbb")
	assertTableEqual(fileTable, { "ccc", "ddd", "eee/fff" })
end

function testGetCommonPathFromSpaceInPaths ()
	local paths = { "/aa a/b bb/ ccc", "/aa a/b bb/ddd ", "/aa a/b bb/e e e/fff" }
	local commonInPath, fileTable = ext.getCommonPath(paths)
	assertEqual(commonInPath, "/aa a/b bb")
	assertTableEqual(fileTable, { " ccc", " ddd", "e e e/fff" })
end

function testGetCommonPathFromFewMatchingPaths ()
	local paths = { "/aaa/bbb/ccc", "/aaa/bbb/ddd", "/aaa2/bbb2/eee/fff" }
	local commonInPath, fileTable = ext.getCommonPath(paths)
	assertEqual(commonInPath, "")
	assertTableEqual(fileTable, paths)
end

function testGetCommonPathFromNoMatchingPaths ()
	local paths = { "/aaa1/bbb1/ccc", "/aaa2/bbb2/ddd", "/aa3/bb3/eee/fff" }
	local commonInPath, fileTable = ext.getCommonPath(paths)
	assertEqual(commonInPath, "")
	assertTableEqual(fileTable, paths)
end

-- ------------------------------------------------------------
-- Testes para findRelativePath (baseDir, path)
-- ------------------------------------------------------------

function testFindRelativePathInSubDir ()
	local baseDir = "/aaa/bbb/ccc"
	local path = "/aaa/bbb/ccc/ddd"
	local result = ext.findRelativePath(baseDir, path)
	assertEqual(result, "ddd")
end

function testFindRelativePathInSiblingDir ()
	local baseDir = "/aaa/bbb/ccc"
	local path = "/aaa/bbb/ddd"
	local result = ext.findRelativePath(baseDir, path)
	assertEqual(result, "../ddd")
end

function testFindRelativePathWithSpaceInPath ()
	local baseDir = "/a aa/bb b/ ccc"
	local path = "/a aa/bb b/ddd "
	local result = ext.findRelativePath(baseDir, path)
	assertEqual(result, "../ddd ")
end

function testFindRelativePathInParentDir ()
	local baseDir = "/aaa/bbb/ccc"
	local path = "/aaa/ddd"
	local result = ext.findRelativePath(baseDir, path)
	assertEqual(result, "../../ddd")
end

function testFindRelativePathInRootDir ()
	local baseDir = "/aaa/bbb/ccc"
	local path = "/ddd"
	local result = ext.findRelativePath(baseDir, path)
	assertEqual(result, "../../../ddd")
end

function testFindRelativePathWithNoBaseDir ()
	local baseDir = ""
	local path = "/ddd/eee/fff"
	local result = ext.findRelativePath(baseDir, path)
	assertEqual(result, "ddd/eee/fff") -- Assume que basedir é "/"
end

function testFindRelativePathWithBaseDirAsCurrentDir ()
	local baseDir = "."
	local path = "./ddd/eee/"
	local result = ext.findRelativePath(baseDir, path)
	assertEqual(result, "ddd/eee/")
end

-- ------------------------------------------------------------
-- Testes para mktemp (path)
-- ------------------------------------------------------------

function testMktempWithSpecifiedPath ()
	local path = _createRandomDir()
	local fileName = ext.mktemp(path)
	local filePath = path.."/"..fileName
	local fileWasCreated = _isFile(filePath)
	assertTrue(is_string(fileName))
	assertNotEqual(fileName, "")
	assertTrue(fileWasCreated)
end

function testMktempWithSpaceInPath ()
	local path = "dir name with space" 
	local sandboxPath = _mkdirSandbox(path)
	local fileName = ext.mktemp(sandboxPath)
	local filePath = sandboxPath.."/"..fileName
	local fileWasCreated = _isFile(filePath)
	assertTrue(is_string(fileName))
	assertNotEqual(fileName, "")
	assertTrue(fileWasCreated)
end

function testMktempWithNoSpecifiedPath ()
	local fileName = ext.mktemp()	
	local filePath = _nameInSandbox(fileName)
	local fileWasCreated = _isFile(filePath)
	assertTrue(is_string(fileName))
	assertNotEqual(fileName, "")
	assertTrue(fileWasCreated)
end

-- ------------------------------------------------------------
-- Testes para grep (arq, pattern, firstOnly)
-- ------------------------------------------------------------

function testGrepWithSingleMatch ()
	local fileName = _createRandomFile()
	local line1 = "line1 line1 line1"
	local line2 = "line2 _FIND_ line2"
	local line3 = "line3 line3 line3"
	local content = line1.."\n"..line2.."\n"..line3
	_writeFile(fileName, content)
	local result = ext.grep(fileName, "_FIND_", false)
	assertTrue(is_table(result))
	assertTableEqual(result, { line2 })
end

function testGrepWithMultipleMatches ()
	local fileName = _createRandomFile()
	local line1 = "line1 _FIND_ line1"
	local line2 = "line2 _FIND_ line2"
	local line3 = "line3 _FIND_ line3"
	local content = line1.."\n"..line2.."\n"..line3
	_writeFile(fileName, content)
	local result = ext.grep(fileName, "_FIND_", false)
	assertTrue(is_table(result))
	assertTableEqual(result, { line1, line2, line3 })
end

function testGrepWithSpaceInFileName ()
	local fileName = "file name with space"
	local sandboxFileName = _nameInSandbox(fileName)
	local line1 = "line1 _FIND_ line1"
	local line2 = "line2 _FIND_ line2"
	local line3 = "line3 _FIND_ line3"
	local content = line1.."\n"..line2.."\n"..line3
	_writeFile(sandboxFileName, content)
	local result = ext.grep(fileName, "_FIND_", false)
	assertTrue(is_table(result))
	assertTableEqual(result, { line1, line2, line3 })
end

function testGrepWithNoMatches ()
	local fileName = _createRandomFile()
	local line1 = "line1 line1 line1"
	local line2 = "line2 line2 line2"
	local line3 = "line3 line3 line3"
	local content = line1.."\n"..line2.."\n"..line3
	_writeFile(fileName, content)
	local result = ext.grep(fileName, "_FIND_", false)
	assertNil(result)
end

function testGrepWithSingleMatchReturningFirstMatchOnly ()
	local fileName = _createRandomFile()
	local line1 = "line1 line1 line1"
	local line2 = "line2 _FIND_ line2"
	local line3 = "line3 line3 line3"
	local content = line1.."\n"..line2.."\n"..line3
	_writeFile(fileName, content)
	local result = ext.grep(fileName, "_FIND_", true)
	assertTrue(is_string(result))
	assertEqual(result, line2)
end

function testGrepWithMultipleMatchesReturningFirstMatchOnly ()
	local fileName = _createRandomFile()
	local line1 = "line1 _FIND_ line1"
	local line2 = "line2 _FIND_ line2"
	local line3 = "line3 _FIND_ line3"
	local content = line1.."\n"..line2.."\n"..line3
	_writeFile(fileName, content)
	local result = ext.grep(fileName, "_FIND_", true)
	assertTrue(is_string(result))
	assertEqual(result, line1)
end

function testGrepWithNoMatchesReturningFirstMatchOnly ()
	local fileName = _createRandomFile()
	local line1 = "line1 line1 line1"
	local line2 = "line2 line2 line2"
	local line3 = "line3 line3 line3"
	local content = line1.."\n"..line2.."\n"..line3
	_writeFile(fileName, content)
	local result = ext.grep(fileName, "_FIND_", true)
	assertNil(result)
end

-- ------------------------------------------------------------
-- Testes para writeMsg (fileName, message)
-- ------------------------------------------------------------

function testWriteMsgInExistingEmptyFile ()
	local fileName = _createRandomFile()
	local msg = "TEST_MSG"
	ext.writeMsg(fileName, msg)
	local content = _readFile(fileName)
	assertEqual(content, msg.."\n") -- Volta com uma quebra de linha a mais
end

function testWriteMsgWithSpaceInFileName ()
	local fileName = "file name with space"
	local sandboxFileName = _nameInSandbox(fileName)
	local msg = "TEST_MSG"
	ext.writeMsg(fileName, msg)
	local content = _readFile(sandboxFileName)
	assertEqual(content, msg.."\n") -- Volta com uma quebra de linha a mais
end

function testWriteMsgInExistingNonEmptyFile ()
	local fileName = _createRandomFile()
	local line1 = "line1 line1 line1"
	local line2 = "line2 line2 line2"
	local line3 = "line3 line3 line3"
	local previousContent = line1.."\n"..line2.."\n"..line3.."\n"
	_writeFile(fileName, previousContent)
	local msg = "TEST_MSG"
	ext.writeMsg(fileName, msg)
	local content = _readFile(fileName)
	assertEqual(content, previousContent..msg.."\n")
end

function testWriteMsgInNonExistingFile ()
	local fileName = _getRandomFileName()
	local msg = "TEST_MSG"
	ext.writeMsg(fileName, msg)
	local content = _readFile(fileName)
	assertEqual(content, msg.."\n")
end

function testWriteMsgWithEmptyMsg ()
	local fileName = _createRandomFile()
	local line1 = "line1 line1 line1"
	local line2 = "line2 line2 line2"
	local line3 = "line3 line3 line3"
	local previousContent = line1.."\n"..line2.."\n"..line3
	_writeFile(fileName, previousContent)
	local msg = ""
	ext.writeMsg(fileName, msg)
	local content = _readFile(fileName)
	assertEqual(content, previousContent.."\n")
end

-- ------------------------------------------------------------
-- Testes para sleep (sec)
-- ------------------------------------------------------------

function testSleep ()
	local previousTime = os.time()
	local time = 5
	local status, err = pcall(ext.sleep, time)
	local currentTime = os.time()
	local delta = currentTime - previousTime
	assertTrue(status)
	assertNil(err)
	assertTrue(delta >= time)
end

-- ------------------------------------------------------------
-- Testes para getFormula (value)
-- ------------------------------------------------------------

function testGetFormulaWithSpaces()
	local formula = "aaa__Space__bbb__Space__ccc"
	local result = ext.getFormula(formula)
	assertEqual(result, "aaa bbb ccc")
end

function testGetFormulaWithUnderline()
	local formula = "aaa__Underline__bbb__Underline__ccc"
	local result = ext.getFormula(formula)
	assertEqual(result, "aaa_bbb_ccc")
end

function testGetFormulaWithPlusSigns()
	local formula = "aaa__PlusSign__bbb__PlusSign__ccc"
	local result = ext.getFormula(formula)
	assertEqual(result, "aaa+bbb+ccc")
end

function testGetFormulaWithMinusSigns()
	local formula = "aaa__MinusSign__bbb__MinusSign__ccc"
	local result = ext.getFormula(formula)
	assertEqual(result, "aaa-bbb-ccc")
end

function testGetFormulaWithSlashes()
	local formula = "aaa__Slash__bbb__Slash__ccc"
	local result = ext.getFormula(formula)
	assertEqual(result, "aaa/bbb/ccc")
end

function testGetFormulaWithAsterisks()
	local formula = "aaa__Asterisk__bbb__Asterisk__ccc"
	local result = ext.getFormula(formula)
	assertEqual(result, "aaa*bbb*ccc")
end

function testGetFormulaWithPercents()
	local formula = "aaa__Percent__bbb__Percent__ccc"
	local result = ext.getFormula(formula)
	assertEqual(result, "aaa%bbb%ccc")
end

function testGetFormulaWithDots()
	local formula = "aaa__Dot__bbb__Dot__ccc"
	local result = ext.getFormula(formula)
	assertEqual(result, "aaa.bbb.ccc")
end

function testGetFormulaWithRoundBrackets()
	local formula = "aaa__OpenRoundBracket__bbb__CloseRoundBracket__ccc"
	local result = ext.getFormula(formula)
	assertEqual(result, "aaa(bbb)ccc")
end

function testGetFormulaWithSquareBrackets()
	local formula = "aaa__OpenSquareBracket__bbb__CloseSquareBracket__ccc"
	local result = ext.getFormula(formula)
	assertEqual(result, "aaa[bbb]ccc")
end

function testGetFormulaWithCurlyBrackets()
	local formula = "aaa__OpenCurlyBracket__bbb__CloseCurlyBracket__ccc"
	local result = ext.getFormula(formula)
	assertEqual(result, "aaa{bbb}ccc")
end

function testGetFormulaWithSemiColons()
	local formula = "aaa__SemiColon__bbb__SemiColon__ccc"
	local result = ext.getFormula(formula)
	assertEqual(result, "aaa;bbb;ccc")
end

function testGetFormulaWithLessThanSigns()
	local formula = "aaa__LessThan__bbb__LessThan__ccc"
	local result = ext.getFormula(formula)
	assertEqual(result, "aaa<bbb<ccc")
end

function testGetFormulaWithLargeThanSigns()
	local formula = "aaa__LargeThan__bbb__LargeThan__ccc"
	local result = ext.getFormula(formula)
	assertEqual(result, "aaa>bbb>ccc")
end

function testGetFormulaWithEqualsSigns()
	local formula = "aaa__EqualsSign__bbb__EqualsSign__ccc"
	local result = ext.getFormula(formula)
	assertEqual(result, "aaa=bbb=ccc")
end

function testGetFormulaWithCarets()
	local formula = "aaa__Caret__bbb__Caret__ccc"
	local result = ext.getFormula(formula)
	assertEqual(result, "aaa^bbb^ccc")
end

function testGetFormulaWithInvalidSymbol()
	local formula = "aaa__InvalidSymbol__bbb__InvalidSymbol__ccc"
	local result = ext.getFormula(formula)
	assertEqual(result, "aaa__InvalidSymbol__bbb__InvalidSymbol__ccc")
end

function testGetFormulaWithNoMatches()
	local formula = "aaabbbccc"
	local result = ext.getFormula(formula)
	assertEqual(result, formula)
end

function testGetFormulaWithEmptyFormula()
	local formula = ""
	local result = ext.getFormula(formula)
	assertEqual(result, formula)
end

-- ------------------------------------------------------------
-- Fim dos testes
-- ------------------------------------------------------------
if not _mkdir(SANDBOX_BASE_DIR) then
	print("[ERROR] Could not create sandbox directory")
	os.exit(-1)
end

runTests()

if not _remove(SANDBOX_BASE_DIR) then
	print("[WARNING] Could not remove sandbox directory")
end

os.exit(numFailedTests()) -- retorna o número de falhas como código de saída

