Scripts 'make_dist' and 'test' ready

This commit is contained in:
perro tuerto 2023-03-22 20:08:06 -07:00
parent ddb9c68e82
commit 49ac3f53fc
11 changed files with 367 additions and 141 deletions

View File

@ -40,11 +40,19 @@ Enter the repo:
Inside, do the tests:
sh scripts/test.sh
pandoc lua scripts/test.lua
For other kind of tests, do:
sh scripts/test.sh -h
pandoc lua scripts/test.lua -h
For other scripts, do:
pandoc lua scripts/SCRIPT
For example, do:
pandoc lua scripts/make_dist.lua
Contribute!

122
dist/lin.lua vendored
View File

@ -6258,6 +6258,105 @@ do
package.preload[module_name] = nil
end
local fnl = mod
------------------------------------ MODS ------------------------------------
-- Tries popen
-- @param ... string: Chunks for popen
-- @return boolean, string: Status and output of popen
function io.try(...)
local cmd = table.concat({...}, " ") .. " 2>&1"
local handle = io.popen(cmd)
local output = handle:read("*a")
local status = (handle:close() ~= nil and true or false)
return status, output
end
-- Gets OS short name
-- It is just intented to know if it is Linux, macOS or Windows.
-- @return string: "linux" or "macos" or "windows"
function os.uname()
local status, output = io.try("uname")
if status then
output = output:gsub(" .*", ""):lower()
if output ~= "linux" then
return "macos"
end
return "linux"
end
return "windows"
end
-- Checks if OS is windows
-- @return boolean: Windows or not
function os.iswin()
return os.uname() == "windows"
end
-- Checks if OS is Unix
-- @return boolean: Unix or not
function os.isunix()
return os.uname() ~= "windows"
end
-- Changes newlines so everything is in one line
-- @return string: String with formatted newlines as literal "\n"
function string:linearize()
return self:gsub("\n", "\\\\n")
end
-- Checks if string is empty
-- @return boolean: Empty or not
function string:isempty()
return self == ''
end
function string:lstrip()
return self:gsub("^%s+", "")
end
function string:rstrip()
return self:gsub("%s+$", "")
end
function string:strip()
return self:lstrip():rstrip()
end
-- The following are heavily influenced by Python pathlib
-- Check: https://docs.python.org/3/library/pathlib.html
-- Checks if string is a file or directory
-- @return boolean: Exists or not
function string:exists()
return os.rename(self, self) ~= nil
end
-- Checks if string is a file
-- @return boolean: File or not
function string:isfile()
if self:exists() then
return io.open(self, "a+") ~= nil
end
return false
end
-- Checks if string is a directory
-- @return boolean: Directory or not
function string:isdir()
if self:exists() then
return io.open(self, "a+") == nil
end
return false
end
-- Reads file content
-- @return string or nil: File content or nil
function string:read_text()
if self:exists() then
return io.open(self):read("*a")
end
end
----------------------------------- NATURAL -----------------------------------
local nat = {}
@ -6265,29 +6364,8 @@ local nat = {}
function nat.get(str)
return str
end
----------------------------------- LITERATE ----------------------------------
-- Types functions extensions
-- Changes newlines so everything is in one line
function string:linearize()
return self:gsub("\n", "\\\\n")
end
-- Checks if is empty
function string:isempty()
return self == ''
end
-- Checks if is directory
function string:isdir()
if self ~= "." and os.rename(self, self) == nil then
return false
end
return true
end
-- Variable for all literate stuff
local lit = {}
@ -6331,6 +6409,7 @@ function lit.checkmetatype(type, meta, key)
local err = ""
if type ~= mtype then
if type == "path" then
-- TODO
if not(pandoc.path.directory(mval):isdir()) then
err = "Invalid path '" .. mval .. "' in key '" .. key .. "'"
end
@ -6448,7 +6527,6 @@ function lit.puts(msg, kind)
end
function lit.parseyaml(rawyaml)
-- TODO: avoid popen?
local yaml = io.popen("pandoc -t json <<<\"" .. rawyaml .. "\" 2>&1")
if yaml:read("*l"):sub(1, 1) == "{" then
yaml = pandoc.read(rawyaml).meta

45
scripts/make_dist.lua Normal file
View File

@ -0,0 +1,45 @@
-- Adds Lua custom extensions
require "../src/extensions"
function make_dist()
-- Variables
local name = "lin.lua"
local dist = pandoc.path.join({"dist", name})
local license = string.strip([[
Computable Pandoc & Fennel Bundle:
A Pandoc filter for literate and natural programming
Computable Pandoc:
(C) 2023 perro hi@perrotuerto.blog
License: GPLv3 https://git.cuates.net/perro/computable-pandoc/src/branch/no-masters/LICENSE.txt
Source: https://git.cuates.net/perro/computable-pandoc
Fennel:
(C) 2016-2023 Calvin Rose and contributors
License: MIT License https://git.sr.ht/~technomancy/fennel/tree/main/item/LICENSE
Source: https://sr.ht/~technomancy/fennel or https://github.com/bakpakin/Fennel/issues
Website: https://fennel-lang.org
]])
function chomp(str, without)
local without = without or false
str = string.read_text(str):strip()
str = str:gsub('\n+--[^\n]+\nrequire "extensions"', "")
if without then
return str:gsub("\n[^\n]+$", "")
end
return "\n" .. str .. "\n"
end
local ext = chomp("src/extensions.lua")
local pan = chomp("src/pandoc.lua")
local fnl = chomp("opt/fennel.lua", true)
local nat = chomp("src/natural.lua", true)
local lit = chomp("src/literate.lua", true)
-- Bundles Fennel and Computable Pandoc
file = io.open(dist, "w")
file:write("--[[\n", license, "\n]]--\n")
file:write(fnl, "\nlocal fnl = mod\n", ext, nat, lit, pan)
file:close()
end
make_dist()

View File

@ -1,26 +0,0 @@
# Makes distribution release
# Variables
NAME="lin.lua"
DIST=dist/$NAME
LICENSE="--[[
Computable Pandoc & Fennel Bundle:
A Pandoc filter for literate and natural programming
Computable Pandoc:
(C) 2023 perro hi@perrotuerto.blog
License: GPLv3 https://git.cuates.net/perro/computable-pandoc/src/branch/no-masters/LICENSE.txt
Source: https://git.cuates.net/perro/computable-pandoc
Fennel:
(C) 2016-2023 Calvin Rose and contributors
License: MIT License https://git.sr.ht/~technomancy/fennel/tree/main/item/LICENSE
Source: https://sr.ht/~technomancy/fennel or https://github.com/bakpakin/Fennel/issues
Website: https://fennel-lang.org
]]--"
# Bundles Fennel and computable Pandoc
(echo "$LICENSE") > $DIST
head -n -1 opt/fennel.lua >> $DIST
echo "local fnl = mod" >> $DIST
head -n -1 src/natural.lua >> $DIST
head -n -1 src/literate.lua >> $DIST
cat src/pandoc.lua >> $DIST

108
scripts/test.lua Normal file
View File

@ -0,0 +1,108 @@
-- Adds Lua custom extensions
require "../src/extensions"
require "../scripts/make_dist"
-- Variables
local filter = "-L dist/lin.lua"
local verbose = ""
local trace = ""
local files = {}
local cmds = {
["unix"] = {
["pandoc"] = "pandoc ",
["clear"] = "clear ",
["ls"] = "ls ",
},
["win"] = {
["pandoc"] = "pandoc.exe ",
["clear"] = "cls ",
["ls"] = "dir ",
},
}
-- Prints help
local function help()
local cmd = " pandoc lua script/test.lua"
print(table.concat({
"Usage:",
cmd .. " [OPTIONS] [FILES]",
"Options",
" -V --verbose Prints verbose debbuging output",
" -t --trace Prints diagnostic output tracing parser progress",
" -h --help Prints this help",
"Examples:",
cmd .. " Tests for 'tests/*.*",
cmd .. " -V Verbose tests for 'tests/*.*'",
cmd .. " -t Tests and tracing for 'tests/*.*'",
cmd .. " tests/fail* Tests for 'tests/fail*'",
cmd .. " -Vt tests/fail* Verbose tests and tracing for 'tests/fail*'",
cmd .. " -h Display this help",
}, "\n"))
os.exit()
end
-- Gets command according to OS
local function getcmd(str)
local system = (os.isunix() and "unix" or "win")
return cmds[system][str]
end
-- Obtains result as "pass" | "fail" | "diff" (AST doesn't match)
local function getresult(file, f, v, t)
local tmp, name = "tmp.json", pandoc.path.filename(file)
local json = pandoc.path.join({"tests", "asts", name .. ".json"})
local ok, out = io.try(getcmd("pandoc"), f, v, t, "-t json", "-o", tmp, file)
local json1, json2 = tmp:read_text(), json:read_text()
os.remove("tmp.json")
if (ok and json2 == nil) or (ok and json1 == json2) then
return "pass", out:strip()
elseif ok and json1 ~= json2 then
return "diff", out:strip()
else
return "fail", out:strip()
end
end
-- Parses args
for _, a in ipairs(arg) do
if a:match("^-.*h.*") then
help()
elseif a == "-V" or a == "--verbose" then
verbose = "--verbose"
elseif a == "-t" or a == "--trace" then
trace = "--trace"
elseif a == "-Vt" or a == "-tV" then
verbose = "--verbose"
trace = "--trace"
elseif a:match("^-") == nil then
table.insert(files, pandoc.path.normalize(a))
end
end
-- Default files
if #files == 0 then
for file in io.popen(getcmd("ls") .. "tests"):lines() do
if file ~= "asts" then
table.insert(files, pandoc.path.join({"tests", file}))
end
end
end
-- Makes distribution bundle
make_dist()
-- Clears terminal
os.execute(getcmd("clear"))
print "🐾 Starting tests"
-- Does tests
for _, file in ipairs(files) do
local expectation = pandoc.path.filename(file):gsub("%W.+$", "")
local result, output = getresult(file, filter, verbose, trace)
print("⚗️ " .. file .. ":")
print(" Expect: " .. expectation)
print(" Result: " .. result)
if #verbose > 0 or #trace > 0 then
print(output)
end
end

View File

@ -1,71 +0,0 @@
# Makes tests
# Variables
FILTER=dist/lin.lua
FILES="tests/*.md"
VERBOSE=""
AST=false
CMD="sh $0"
# Prints help
echo_help () {
echo "Usage:"
echo " $CMD [-vah] [FILES]"
echo "Examples:"
echo " $CMD Tests for 'tests/*.md'"
echo " $CMD -v Verbose tests for 'tests/*.md'"
echo " $CMD -a Tests and AST for 'tests/*.md'"
echo " $CMD tests/fail* Tests for 'tests/fail*'"
echo " $CMD -va tests/fail* Verbose tests and AST for 'tests/fail*'"
echo " $CMD -h Display this help"
exit
}
# Obtains result as "pass" | "fail" | "diff" (AST doesn't match)
get_result () {
result=$([[ $1 -ne 0 ]] && echo "fail" || echo "pass")
if [ -f $2.json ]; then
diff1=$(cat tmp.json | jq)
diff2=$(cat $2.json | jq)
difference=$(diff <( printf '%s\n' "$diff1" ) <( printf '%s\n' "$diff2" ))
result=$([[ $? -eq 0 ]] && echo "pass" || echo "diff")
fi
echo $result
}
# Checks options
while getopts ':vah' opt; do
case "$opt" in
v) VERBOSE="--verbose" ; shift ;;
a) AST=true ; shift ;;
h) echo_help ;;
?) echo "ERROR: only -v, -a or -h is allowed" ; exit 1 ;;
esac
done
# Checks for files
if [ $# -ne 0 ]; then
for file in $*; do
if [ ! -f $file ]; then
echo "ERROR: '$file' is not a file; do '$CMD -h' for more info" ; exit 1
fi
done
FILES=$*
fi
# Makes distribution bundle
sh scripts/make_dist.sh
# Does tests
clear && echo "🐾 Starting tests"
for file in $FILES; do
echo "⚗️ $file:"
expectation=${file:6:4}
ast=$(pandoc $VERBOSE -L $FILTER -t json -o tmp.json $file)
result=$(get_result $? $file)
echo " Expect: $expectation"
echo " Result: $result"
[ "$VERBOSE" = "--verbose" ] && echo -e "$ast"
[ "$AST" = true ] && pandoc -L $FILTER -t native $file
rm tmp.json
done

98
src/extensions.lua Normal file
View File

@ -0,0 +1,98 @@
------------------------------------ MODS ------------------------------------
-- Tries popen
-- @param ... string: Chunks for popen
-- @return boolean, string: Status and output of popen
function io.try(...)
local cmd = table.concat({...}, " ") .. " 2>&1"
local handle = io.popen(cmd)
local output = handle:read("*a")
local status = (handle:close() ~= nil and true or false)
return status, output
end
-- Gets OS short name
-- It is just intented to know if it is Linux, macOS or Windows.
-- @return string: "linux" or "macos" or "windows"
function os.uname()
local status, output = io.try("uname")
if status then
output = output:gsub(" .*", ""):lower()
if output ~= "linux" then
return "macos"
end
return "linux"
end
return "windows"
end
-- Checks if OS is windows
-- @return boolean: Windows or not
function os.iswin()
return os.uname() == "windows"
end
-- Checks if OS is Unix
-- @return boolean: Unix or not
function os.isunix()
return os.uname() ~= "windows"
end
-- Changes newlines so everything is in one line
-- @return string: String with formatted newlines as literal "\n"
function string:linearize()
return self:gsub("\n", "\\\\n")
end
-- Checks if string is empty
-- @return boolean: Empty or not
function string:isempty()
return self == ''
end
function string:lstrip()
return self:gsub("^%s+", "")
end
function string:rstrip()
return self:gsub("%s+$", "")
end
function string:strip()
return self:lstrip():rstrip()
end
-- The following are heavily influenced by Python pathlib
-- Check: https://docs.python.org/3/library/pathlib.html
-- Checks if string is a file or directory
-- @return boolean: Exists or not
function string:exists()
return os.rename(self, self) ~= nil
end
-- Checks if string is a file
-- @return boolean: File or not
function string:isfile()
if self:exists() then
return io.open(self, "a+") ~= nil
end
return false
end
-- Checks if string is a directory
-- @return boolean: Directory or not
function string:isdir()
if self:exists() then
return io.open(self, "a+") == nil
end
return false
end
-- Reads file content
-- @return string or nil: File content or nil
function string:read_text()
if self:exists() then
return io.open(self):read("*a")
end
end

View File

@ -1,24 +1,7 @@
----------------------------------- LITERATE ----------------------------------
-- Types functions extensions
-- Changes newlines so everything is in one line
function string:linearize()
return self:gsub("\n", "\\\\n")
end
-- Checks if is empty
function string:isempty()
return self == ''
end
-- Checks if is directory
function string:isdir()
if self ~= "." and os.rename(self, self) == nil then
return false
end
return true
end
-- Adds Lua custom extensions
require "extensions"
-- Variable for all literate stuff
local lit = {}
@ -63,6 +46,7 @@ function lit.checkmetatype(type, meta, key)
local err = ""
if type ~= mtype then
if type == "path" then
-- TODO
if not(pandoc.path.directory(mval):isdir()) then
err = "Invalid path '" .. mval .. "' in key '" .. key .. "'"
end
@ -180,7 +164,6 @@ function lit.puts(msg, kind)
end
function lit.parseyaml(rawyaml)
-- TODO: avoid popen?
local yaml = io.popen("pandoc -t json <<<\"" .. rawyaml .. "\" 2>&1")
if yaml:read("*l"):sub(1, 1) == "{" then
yaml = pandoc.read(rawyaml).meta

View File

@ -1,5 +1,8 @@
----------------------------------- NATURAL -----------------------------------
-- Adds Lua custom extensions
require "extensions"
local nat = {}
function nat.get(str)