Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
227 changes: 71 additions & 156 deletions indra/alscript/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -237,168 +237,83 @@ if(AL_BUILD_TESTS)
templates_define
"AL_SCRIPT_TEMPLATES_DIR=\"${INDRA_SOURCE_DIR}/newview/app_settings/script_templates\""
)
al_add_test(
alluauservice
PROJECT alscript
LIBRARIES alscript llcommon
DEFINES ${definitions_defines} ${templates_define}
# What every binary of alscript's tests sets up once, as the viewer has it
# before it checks a script, and the state guard's checks on what the
# script engines keep for the process.
add_library(alscript_test_checks OBJECT tests/alscript_test_checks.cpp)
target_link_libraries(
alscript_test_checks
PRIVATE al::flags al_test_support alscript llcommon ll::tailslide
)
# Completion and signature help over a fragment, against the whole
# script, at the places a scripter asks, over every SLua script to hand;
# the places found by Luau's own lexer.
al_add_test(
alluaufragment
target_compile_definitions(alscript_test_checks PRIVATE ${definitions_defines})
set_target_properties(alscript_test_checks PROPERTIES FOLDER "Tests/alscript")

# One Catch2 binary for alscript's tests, each test file run in a process
# of its own. The SLua checks, and LSL written again as SLua, run again
# with Luau's new type solver, which a scripter may choose
# (ALScriptLuauSolver): the same tests, told by the environment.
al_add_test_binary(
alscript_tests
PROJECT alscript
LIBRARIES alscript llcommon ll::slua
SOURCES
tests/aldiskcache_test.cpp
tests/aldiskincludes_test.cpp
tests/alincludeidentity_test.cpp
tests/alincludesearch_test.cpp
tests/allinelabel_test.cpp
tests/allslconsts_test.cpp
tests/allslcosts_test.cpp
tests/allsleffects_test.cpp
tests/allsloptimizer_test.cpp
tests/allslservice_test.cpp
tests/allsltoslua_test.cpp
tests/alluauconfig_test.cpp
tests/alluaufragment_test.cpp
tests/alluaunavigation_test.cpp
tests/alluauservice_test.cpp
tests/almasterburst_test.cpp
tests/almasterindex_test.cpp
tests/almasterlinks_test.cpp
tests/almastermatch_test.cpp
tests/almasterplan_test.cpp
tests/almasterqueue_test.cpp
tests/almasterwatch_test.cpp
tests/almessagemap_test.cpp
tests/almodulelook_test.cpp
tests/alnotecardformat_test.cpp
tests/alpreprocessor_test.cpp
tests/alpreprocessorc11_test.cpp
tests/alscriptenvelope_test.cpp
tests/alscriptfixes_test.cpp
tests/alscriptformatter_test.cpp
tests/alscriptjoblane_test.cpp
tests/alscriptlexicon_test.cpp
tests/alscriptlintpass_test.cpp
tests/alscriptmessages_test.cpp
tests/alscriptnameindex_test.cpp
tests/alscriptoutlinepairs_test.cpp
tests/alscriptsnapshot_test.cpp
tests/alscriptstack_test.cpp
tests/alscripttempfiles_test.cpp
tests/alscripttextcache_test.cpp
tests/alscriptweight_test.cpp
tests/alsourcemap_test.cpp
tests/aluploadheader_test.cpp
SUPPORT alscript_test_checks llcommon_test_checks
LIBRARIES alscript llcommon ll::slua ll::tailslide
DEFINES
${definitions_defines}
${templates_define}
"AL_ALSCRIPT_TEST_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/tests\""
)
# Where a name is declared and used, across a script and the modules it
# requires.
al_add_test(
alluaunavigation
PROJECT alscript
LIBRARIES alscript llcommon
DEFINES ${definitions_defines}
)
al_add_test(
allslservice
PROJECT alscript
LIBRARIES alscript llcommon
DEFINES ${definitions_defines} ${templates_define}
)
# Each fix made over a real check, applied, and the text checked again.
al_add_test(
alscriptfixes
PROJECT alscript
LIBRARIES alscript llcommon
DEFINES ${definitions_defines}
)
# The studio's own lints, each over real checks, with its fix made.
al_add_test(
alscriptlintpass
PROJECT alscript
LIBRARIES alscript llcommon
DEFINES ${definitions_defines}
)
# The SLua checks, and LSL written again as SLua, again with Luau's new
# type solver, which a scripter may choose (ALScriptLuauSolver): the same
# tests, told by the environment.
foreach(
test
alluauservice
alluaufragment
alluaunavigation
alscriptfixes
alscriptlintpass
allsltoslua
)
add_test(
NAME INTEGRATION_TEST_RUNNER_${test}_newsolver
COMMAND $<TARGET_FILE:INTEGRATION_TEST_${test}>
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set_tests_properties(
INTEGRATION_TEST_RUNNER_${test}_newsolver
PROPERTIES
ENVIRONMENT "AL_TEST_LUAU_SOLVER=new"
ENVIRONMENT_MODIFICATION "${AL_TEST_ENVIRONMENT}"
SKIP_RETURN_CODE 125
)
endforeach()
# What a script weighs: SLua by its bytecode, LSO by Tailslide's image,
# with the grid's builtins loaded.
al_add_test(
alscriptweight
PROJECT alscript
LIBRARIES alscript llcommon
DEFINES ${definitions_defines}
)
al_add_test(aldiskincludes PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(aldiskcache PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(alincludeidentity PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(alincludesearch PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(allinelabel PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(almodulelook PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(alsourcemap PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(alscriptjoblane PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(alscriptnameindex PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(alscriptoutlinepairs PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(alscriptsnapshot PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(alscripttextcache PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(alscriptstack PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(alscriptenvelope PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(aluploadheader PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(almessagemap PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(alluauconfig PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(alscriptformatter PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(alscriptlexicon PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(alscriptmessages PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(alnotecardformat PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(alscripttempfiles PROJECT alscript LIBRARIES alscript llcommon)
# Disk masters: the changes gathered over a burst, the links and their
# index, the index kept in a file, a master found from what a script says
# or its name, what a send does, the sends underway, and the files watched
# for saves made outside.
al_add_test(almasterburst PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(almasterindex PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(almasterlinks PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(almastermatch PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(almasterplan PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(almasterqueue PROJECT alscript LIBRARIES alscript llcommon)
al_add_test(almasterwatch PROJECT alscript LIBRARIES alscript llcommon)
# The preprocessor against C11's 6.10, clause by clause.
al_add_test(alpreprocessorc11 PROJECT alscript LIBRARIES alscript llcommon)
# What LSL may change and the order it runs in, over scripts parsed with
# the grid's builtins loaded.
al_add_test(
allsleffects
PROJECT alscript
LIBRARIES alscript llcommon ll::tailslide
DEFINES ${definitions_defines}
)
# What LSL forms cost on each target: snippet pairs compiled by
# Tailslide, against what the optimizer takes them to cost.
al_add_test(
allslcosts
PROJECT alscript
LIBRARIES alscript llcommon
DEFINES ${definitions_defines}
)
# The const keyword over scripts parsed with the grid's builtins loaded.
al_add_test(
allslconsts
PROJECT alscript
LIBRARIES alscript llcommon
DEFINES ${definitions_defines}
)
# The optimizer's golden files under tests/optimizer/, checked with the
# grid's builtins loaded.
al_add_test(
allsloptimizer
PROJECT alscript
LIBRARIES alscript llcommon
DEFINES ${definitions_defines} "AL_ALSCRIPT_TEST_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/tests\""
)
# LSL written again as SLua, each result checked as SLua against the
# grid's definitions; and Tailslide's own test scripts under
# tests/tailslide/, for their breadth. The comments a toggle makes, as
# Luau's own lexer reads them.
al_add_test(
allsltoslua
PROJECT alscript
LIBRARIES alscript llcommon ll::slua
DEFINES ${definitions_defines} "AL_ALSCRIPT_TEST_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/tests\""
)
# The golden files under tests/preprocessor/: every test_*.lsl beside
# its expected output.
al_add_test(
alpreprocessor
PROJECT alscript
LIBRARIES alscript llcommon ll::slua
DEFINES ${definitions_defines} "AL_ALSCRIPT_TEST_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/tests\""
RERUN newsolver
RERUN_SOURCES
tests/alluaufragment_test.cpp
tests/alluaunavigation_test.cpp
tests/alluauservice_test.cpp
tests/allsltoslua_test.cpp
tests/alscriptfixes_test.cpp
tests/alscriptlintpass_test.cpp
RERUN_ENVIRONMENT AL_TEST_LUAU_SOLVER=new
)
# The preprocessor, the formatter, the optimizer and one analysis of each
# language over big scripts, with the grid's definitions loaded.
Expand Down
4 changes: 3 additions & 1 deletion indra/alscript/lsl/allslservice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1359,6 +1359,9 @@ bool ALLSLService::loadBuiltins(const std::string& path, std::string& error)
added += '\n';
}
}
// This service has them, whatever the table already held: a file
// all of whose names an earlier one loaded is loaded all the same.
mImpl->builtins = true;
error.clear();
if (added.empty())
{
Expand Down Expand Up @@ -1392,7 +1395,6 @@ bool ALLSLService::loadBuiltins(const std::string& path, std::string& error)
const int index = Luau::lslEventIndex(symbol->getName());
symbol->setEventIndex(index > 0 ? index : ++last);
}
mImpl->builtins = true;
return true;
}
// Read here and handed over as text: a path Tailslide opened itself
Expand Down
81 changes: 48 additions & 33 deletions indra/alscript/tests/aldiskcache_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#include "fsyspath.h"
#include "llfile.h"

#include "../test/lltut.h"
#include <catch2/catch_test_macros.hpp>

#include <chrono>
#include <filesystem>
Expand Down Expand Up @@ -69,20 +69,10 @@ namespace
};
}

namespace tut
namespace
{
struct aldiskcache_data
{
};

typedef test_group<aldiskcache_data> aldiskcache_group;
typedef aldiskcache_group::object aldiskcache_object;
aldiskcache_group aldiskcache_instance("aldiskcache");

template<> template<>
void aldiskcache_object::test<1>()
TEST_CASE("aldiskcache: what is blessed and admitted kept until stale or the settings move", "[aldiskcache]")
{
set_test_name("the folders blessed as the preprocessor blesses them, kept a moment or until the settings move; what they admit kept with them");
Scratch s;
const std::string part = s.write("includes/lib/part.lsl", "integer part;\n");
s.write("includes/.lslrc", "{\"include\": [\"lib\"]}");
Expand All @@ -91,51 +81,76 @@ namespace tut
const std::vector<std::string> own{ s.at("includes") };

ALDiskCache::Blessed& first = cache.blessed(own, true, s.at("project/a"), {}, 1, 100.0);
ensure_equals("the scripter's, and what its .lslrc lists", first.includes.folders().size(), size_t(2));
ensure_equals("a file under them admitted", cache.admits(first, part).value_or(""), part);
ensure("what is not there, not", !cache.admits(first, s.at("includes/lib/none.lsl")));
UNSCOPED_INFO("the scripter's, and what its .lslrc lists");
REQUIRE(first.includes.folders().size() == size_t(2));
UNSCOPED_INFO("a file under them admitted");
CHECK(cache.admits(first, part).value_or("") == part);
UNSCOPED_INFO("what is not there, not");
REQUIRE_FALSE(cache.admits(first, s.at("includes/lib/none.lsl")));

// Taken away: still admitted while what is kept is fresh, and the
// folders as they were.
fs::remove(s.under("includes/lib/part.lsl"));
ALDiskCache::Blessed& again = cache.blessed(own, true, s.at("project/a"), {}, 1, 101.0);
ensure("the same kept", &again == &first && cache.admits(again, part).has_value());
{
INFO("the same kept");
CHECK(&again == &first);
REQUIRE(cache.admits(again, part).has_value());
}
std::string text;
ensure("but not read", !cache.read(part, text));
UNSCOPED_INFO("but not read");
CHECK_FALSE(cache.read(part, text));

ALDiskCache::Blessed& later = cache.blessed(own, true, s.at("project/a"), {}, 1, 100.0 + ALDiskCache::FRESH_SECONDS + 0.5);
ensure("a moment later, asked again", !cache.admits(later, part));
UNSCOPED_INFO("a moment later, asked again");
REQUIRE_FALSE(cache.admits(later, part));
s.write("includes/lib/part.lsl", "integer part;\n");
ensure("kept as asked until then", !cache.admits(later, part));
UNSCOPED_INFO("kept as asked until then");
REQUIRE_FALSE(cache.admits(later, part));
ALDiskCache::Blessed& moved = cache.blessed(own, true, s.at("project/a"), {}, 2, 103.0);
ensure("the settings moved: asked again at once", cache.admits(moved, part).has_value());
UNSCOPED_INFO("the settings moved: asked again at once");
REQUIRE(cache.admits(moved, part).has_value());

ALDiskCache::Blessed& plain = cache.blessed(own, false, s.at("project/a"), {}, 2, 103.0);
ensure_equals("SLua's: no .lslrc read", plain.includes.folders().size(), size_t(1));
UNSCOPED_INFO("SLua's: no .lslrc read");
REQUIRE(plain.includes.folders().size() == size_t(1));
ALDiskCache::Blessed& aliased = cache.blessed(own, false, std::string(), { s.at("project") }, 2, 103.0);
ensure_equals("an alias's folder blessed outright", aliased.includes.folders().size(), size_t(2));
ensure_equals("the file at the top of each that has it", cache.atTop(moved, ".lslrc").size(), size_t(1));
UNSCOPED_INFO("an alias's folder blessed outright");
REQUIRE(aliased.includes.folders().size() == size_t(2));
UNSCOPED_INFO("the file at the top of each that has it");
REQUIRE(cache.atTop(moved, ".lslrc").size() == size_t(1));
}

template<> template<>
void aldiskcache_object::test<2>()
TEST_CASE("aldiskcache: a text read again once its time or size changes; upwards kept a moment", "[aldiskcache]")
{
set_test_name("a text read again only once its time or size changes; the configurations up the folders found once a moment");
Scratch s;
const std::string file = s.write("lib/util.lsl", "integer one;\n");
ALDiskCache cache;
std::string text;
ensure("read", cache.read(file, text) && text == "integer one;\n");
REQUIRE(cache.read(file, text));
CHECK(text == "integer one;\n");
s.write("lib/util.lsl", "integer three;\n");
ensure("read again once it changed", cache.read(file, text) && text == "integer three;\n");
ensure("nothing where nothing is", !cache.read(s.at("lib/none.lsl"), text));
{
INFO("read again once it changed");
CHECK(cache.read(file, text));
CHECK(text == "integer three;\n");
}
UNSCOPED_INFO("nothing where nothing is");
CHECK_FALSE(cache.read(s.at("lib/none.lsl"), text));

s.write("a/.luaurc", "{}");
s.write("a/b/c/.luaurc", "{}");
const std::vector<std::string>& up = cache.upwards(s.at("a/b/c"), ".luaurc", 1, 10.0);
ensure("nearest first, to the root", up.size() >= 2 && up[0] == s.at("a/b/c/.luaurc") && up[1] == s.at("a/.luaurc"));
{
INFO("nearest first, to the root");
REQUIRE(up.size() >= 2);
CHECK(up[0] == s.at("a/b/c/.luaurc"));
CHECK(up[1] == s.at("a/.luaurc"));
}
s.write("a/b/.luaurc", "{}");
ensure_equals("kept a moment", cache.upwards(s.at("a/b/c"), ".luaurc", 1, 11.0).size(), up.size());
ensure("then found", cache.upwards(s.at("a/b/c"), ".luaurc", 1, 10.0 + ALDiskCache::FRESH_SECONDS + 1.0)[1] == s.at("a/b/.luaurc"));
UNSCOPED_INFO("kept a moment");
REQUIRE(cache.upwards(s.at("a/b/c"), ".luaurc", 1, 11.0).size() == up.size());
UNSCOPED_INFO("then found");
CHECK(cache.upwards(s.at("a/b/c"), ".luaurc", 1, 10.0 + ALDiskCache::FRESH_SECONDS + 1.0)[1] == s.at("a/b/.luaurc"));
}
}
Loading
Loading