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
5 changes: 2 additions & 3 deletions .github/workflows/test-skripts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ on:
- .github/workflows/test-skripts.yml

concurrency:
group: run-tests
group: run-tests-${{ github.head_ref || github.ref }}
cancel-in-progress: true

permissions:
Expand Down Expand Up @@ -62,7 +62,6 @@ jobs:
rsync -av scripts/ tests/scripts/
mv tests/scripts/libs/singlelinesection.sk tests/scripts/libs/0_singlelinesection.sk
rm -f tests/scripts/utils/testframework.sk
rm -f tests/scripts/libs/pdc.sk
rm -f tests/scripts/utils/configreloadv2.sk


Expand All @@ -74,7 +73,7 @@ jobs:
test_script_directory: tests

# Skript version or ref (tag, branch, or commit)
skript_repo_ref: copy-dir-resources # 2.13.2
skript_repo_ref: ef28bd5 # 2.13.2

# directory containing addon/plugin jars (relative to repo root)
extra_plugins_directory: build/libs
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,13 @@ If you encounter errors such as `Can't understand this expression`, the issue is

Skript loads files alphabetically, with folders being prioritized. To control load order, prefix the Skript file with a folder or a character such as `0_` or `!`
(e.g., `!testframework.sk`)

## TODO

Currents plans include:
- multiline lambda expression
- making the test framework support extending over the skriptlang native test suit

---

**For technical details, I recommend you to use deepwiki**
1 change: 0 additions & 1 deletion docs/pdc.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ Scripts do **not** require syntax changes, but values written by older versions
- Paper server
- Skript
- skript-reflect
- skBee

---

Expand Down
14 changes: 5 additions & 9 deletions docs/testframework.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ test "<test name>" [when <condition>]:
<test body>
```

* `<test name>` must be unique **within the script**
* Tests are registered automatically when the script is parsed
* The optional `when` condition is evaluated immediately before execution

Expand All @@ -75,7 +74,7 @@ Inside a test, the framework provides:
Fully-qualified test identifier:

```
<script>/<test name>
<test name>
```

* **`event-boolean`**
Expand All @@ -90,11 +89,9 @@ Tests are registered automatically at parse time. No explicit registration step
Internal storage format:

```
-test.sk::tests::<script>::<test name>
-test.sk::tests::<test name>
```

Registration is deterministic and isolated per script.

---

## Running Tests
Expand Down Expand Up @@ -125,7 +122,7 @@ run test(s) %strings%
Identifier format:

```
<script>/<test name>
<test name>
```

---
Expand All @@ -135,13 +132,12 @@ Identifier format:
### Expression

```skript
all tests [with test name %-string%] [within|from %-script%]
all tests [with test name %-string%]
```

### Behavior

* No arguments → all tests from all scripts
* `from <script>` → tests scoped to a script
* `with test name <string>` → exact match only

Returned values are fully-qualified test identifiers.
Expand Down Expand Up @@ -356,7 +352,7 @@ Output is suppressed entirely when `with no error message` is specified.

The framework guarantees that:

* Tests are isolated by identifier
* Tests are isolated by themselves
* Registration is implicit and deterministic
* Autorun and manual execution are distinguishable
* Failures are recorded even in non-halting mode
Expand Down
14 changes: 9 additions & 5 deletions scripts/libs/functionsv2.sk
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ expression build lambda args %objects% body %string% noreturn %boolean% script %
set {_functionsv2.sk::ctx::proxy} to new proxy instance of Runnable using {_functionsv2.sk::ctx::functions::*}
else if {_functionsv2.sk::ctx::arity} is 1:
set {_functionsv2.sk::ctx::proxy} to raw expression of {_this}
set {_functionsv2.sk::ctx::functions::accept} to line section {_functionsv2.sk::ctx::body} with runtime args {_functionsv2.sk::ctx::proxy}, {_functionsv2.sk::ctx::args::1} in {_functionsv2.sk::ctx::script}
set {_functionsv2.sk::ctx::functions::accept} to line section {_functionsv2.sk::ctx::body} with args "%{_functionsv2.sk::ctx::proxy}%", "%{_functionsv2.sk::ctx::args::1}%" in {_functionsv2.sk::ctx::script}
set {_functionsv2.sk::ctx::proxy} to new proxy instance of Consumer using {_functionsv2.sk::ctx::functions::*}
else:
set {_functionsv2.sk::ctx::proxy} to raw expression of {_this}
set {_functionsv2.sk::ctx::functions::accept} to line section {_functionsv2.sk::ctx::body} with runtime args {_functionsv2.sk::ctx::proxy}, {_functionsv2.sk::ctx::args::1}, {_functionsv2.sk::ctx::args::2} in {_functionsv2.sk::ctx::script}
set {_functionsv2.sk::ctx::functions::accept} to line section {_functionsv2.sk::ctx::body} with args "%{_functionsv2.sk::ctx::proxy}%", "%{_functionsv2.sk::ctx::args::1}%", "%{_functionsv2.sk::ctx::args::2}%" in {_functionsv2.sk::ctx::script}
set {_functionsv2.sk::ctx::proxy} to new proxy instance of BiConsumer using {_functionsv2.sk::ctx::functions::*}
else:

Expand All @@ -83,11 +83,11 @@ expression build lambda args %objects% body %string% noreturn %boolean% script %
set {_functionsv2.sk::ctx::proxy} to new proxy instance of Supplier using {_functionsv2.sk::ctx::functions::*}
else if {_functionsv2.sk::ctx::arity} is 1:
set {_functionsv2.sk::ctx::proxy} to raw expression of {_this}
set {_functionsv2.sk::ctx::functions::apply} to line section "return %{_functionsv2.sk::ctx::body}%" with runtime args {_functionsv2.sk::ctx::proxy}, {_functionsv2.sk::ctx::args::1} in {_functionsv2.sk::ctx::script}
set {_functionsv2.sk::ctx::functions::apply} to line section "return %{_functionsv2.sk::ctx::body}%" with args "%{_functionsv2.sk::ctx::proxy}%", "%{_functionsv2.sk::ctx::args::1}%" in {_functionsv2.sk::ctx::script}
set {_functionsv2.sk::ctx::proxy} to new proxy instance of Function using {_functionsv2.sk::ctx::functions::*}
else:
set {_functionsv2.sk::ctx::proxy} to raw expression of {_this}
set {_functionsv2.sk::ctx::functions::apply} to line section "return %{_functionsv2.sk::ctx::body}%" with runtime args {_functionsv2.sk::ctx::proxy}, {_functionsv2.sk::ctx::args::1}, {_functionsv2.sk::ctx::args::2} in {_functionsv2.sk::ctx::script}
set {_functionsv2.sk::ctx::functions::apply} to line section "return %{_functionsv2.sk::ctx::body}%" with args "%{_functionsv2.sk::ctx::proxy}%", "%{_functionsv2.sk::ctx::args::1}%", "%{_functionsv2.sk::ctx::args::2}%" in {_functionsv2.sk::ctx::script}
set {_functionsv2.sk::ctx::proxy} to new proxy instance of BiFunction using {_functionsv2.sk::ctx::functions::*}
return {_functionsv2.sk::ctx::proxy}

Expand All @@ -103,6 +103,8 @@ expression:
set {_functionsv2.sk::ctx::args::*} to FextractArgs({_functionsv2.sk::ctx::vars})
set {_functionsv2.sk::ctx::origin} to SkriptLogger.getNode()
set {_functionsv2.sk::ctx::script} to script ({_functionsv2.sk::ctx::origin}.getConfig().getFileName())
if {_functionsv2.sk::ctx::script} is not set: # likely inner lambda
set {_functionsv2.sk::ctx::script} to current script
continue
get:
return build lambda args {_functionsv2.sk::ctx::args::*} body {_functionsv2.sk::ctx::expr} noreturn {_functionsv2.sk::ctx::noreturn} script {_functionsv2.sk::ctx::script}
Expand Down Expand Up @@ -141,7 +143,9 @@ expression:
if size of {_functionsv2.sk::ctx::args::*} is not 2:
stop
set {_functionsv2.sk::ctx::origin} to SkriptLogger.getNode()
set {_functionsv2.sk::ctx::script} to script ({_origin}.getConfig().getFileName())
set {_functionsv2.sk::ctx::script} to script ({_functionsv2.sk::ctx::origin}.getConfig().getFileName())
if {_functionsv2.sk::ctx::script} is not set: # likely inner lambda
set {_functionsv2.sk::ctx::script} to current script
continue
get:
return build lambda args {_functionsv2.sk::ctx::args::*} body {_functionsv2.sk::ctx::expr} noreturn {_functionsv2.sk::ctx::noreturn} script {_functionsv2.sk::ctx::script}
Expand Down
29 changes: 19 additions & 10 deletions scripts/libs/pdc.sk
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,22 @@ expression [devdinc] (pdt|[persistent data ]type) (1:str[ing]|2:int[eger]|3:long
parse:
continue
get:
return switch return parse mark:
case 1 -> PersistentDataType.STRING
case 2 -> PersistentDataType.INTEGER
case 3 -> PersistentDataType.LONG
case 4 -> PersistentDataType.FLOAT
case 5 -> PersistentDataType.DOUBLE
case 6 -> PersistentDataType.BYTE
case 7 -> PersistentDataType.SHORT
case 8 -> PersistentDataType.BOOLEAN
default -> {_none}
if parse mark is 1:
return PersistentDataType.STRING
else if parse mark is 2:
return PersistentDataType.INTEGER
else if parse mark is 3:
return PersistentDataType.LONG
else if parse mark is 4:
return PersistentDataType.FLOAT
else if parse mark is 5:
return PersistentDataType.DOUBLE
else if parse mark is 6:
return PersistentDataType.BYTE
else if parse mark is 7:
return PersistentDataType.SHORT
else if parse mark is 8:
return PersistentDataType.BOOLEAN
else:
return {_none}

49 changes: 20 additions & 29 deletions scripts/libs/singlelinesection.sk
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import:
java.util.HashSet
org.skriptlang.reflect.java.elements.structures.StructImport
ch.njol.skript.log.SkriptLogger
java.lang.String
java.lang.Object

local function extractArgs(vars: object) :: objects:
if {_vars} is instance of ExpressionList:
Expand All @@ -33,46 +35,31 @@ local function extractRuntimeArgs(vars: objects) :: objects:

expression compile line %string% with %object% (1:|2:noreturn) in %script%:
get:
set {_section.sk::single::parser} to ParserInstance.get()
set {_section.sk::single::parser}.[ParserInstance]isActive to true
set {_section.sk::single::parserBackup} to {_section.sk::single::parser}.backup()
set {_section.sk::single::parser}.[ParserInstance]isActive to false
{_section.sk::single::parser}.reset()

set {_section.sk::single::code} to "%expr-1%"
set {_section.sk::single::event} to expr-2
set {_section.sk::single::bais} to new ByteArrayInputStream({_section.sk::single::code}.getBytes())
set {_section.sk::single::name} to "section"

set {_section.sk::single::config} to new Config({_section.sk::single::bais},"compiled single line for single line section: %expr-1%",true,false,":")
set {_section.sk::single::node} to {_section.sk::single::config}.getMainNode()

# a hack to use java calls
set {_section.sk::single::imports} to StructImport.[StructImport]imports.get(expr-3)
if {_section.sk::single::imports} is not set:
set {_section.sk::single::imports} to new HashMap()
set {_section.sk::single::importsLocal} to StructImport.[StructImport]imports.getOrDefault(null, new HashMap())
set {_section.sk::single::keys} to new HashSet({_section.sk::single::imports}.keySet())
{_section.sk::single::keys}.removeAll({_section.sk::single::importsLocal}.keySet())
loop ...{_section.sk::single::keys}:
set {_section.sk::single::javatype} to {_section.sk::single::imports}.get(loop-value)
set {_section.sk::single::javatypeSimpleName} to last element of split "%{_section.sk::single::javatype}%" at "."
# simulating effect command !import <import>
if loop-value is {_section.sk::single::javatypeSimpleName}:
StructImport.registerImport("%{_section.sk::single::javatype}%", null)
else:
StructImport.registerImport("%{_section.sk::single::javatype}% as %loop-value%", null)


set {_section.sk::single::parser} to ParserInstance.get()
set {_section.sk::single::isActiveOrig} to {_section.sk::single::parser}.[ParserInstance]isActive
set {_section.sk::single::parser}.[ParserInstance]isActive to true
set {_section.sk::single::parserBackup} to {_section.sk::single::parser}.backup()
{_section.sk::single::parser}.reset()
{_section.sk::single::parser}.setCurrentScript(expr-3)
{_section.sk::single::parser}.setCurrentEvent({_section.sk::single::name}, SectionEvent.class)
{_section.sk::single::parser}.setCurrentStructure({_section.sk::single::event})

set {_section.sk::single::items} to ScriptLoader.loadItems({_section.sk::single::node})

{_section.sk::single::parser}.restoreBackup({_section.sk::single::parserBackup})
set {_section.sk::single::parser}.[ParserInstance]isActive to {_section.sk::single::isActiveOrig}
return new Trigger(current script, {_section.sk::single::name}, {_section.sk::single::event}, {_section.sk::single::items})


expression [new] [single] line section %string%[ with (1:|2:runtime) [arg[ument]s [variables]] %-objects%][in %-script%]:
expression [new] [single] line section %strings%[ with [arg[ument]s [variables]] %-objects%][in %-script%]:
return type: section
parse:
if expr-3 is not set:
Expand All @@ -82,21 +69,25 @@ expression [new] [single] line section %string%[ with (1:|2:runtime) [arg[ument]
get:
if {_section.sk::single::script} is not set:
set {_section.sk::single::script} to expr-3
if parse mark is 2:
set {_section.sk::single::test::*} to expr-2
if expr-2 is instance of String:
set {_section.sk::single::array} to [Object.class]
set {_section.sk::single::expr2::*} to expr-2
loop {_section.sk::single::expr2::*}:
set {_section.sk::single::expr2} to loop-value
replace "{", "}" with "" in {_section.sk::single::expr2}
set {_section.sk::single::test::%loop-index%} to Variable.newInstance({_section.sk::single::expr2}, {_section.sk::single::array})
set {_section.sk::single::args::*} to extractRuntimeArgs({_section.sk::single::test::*})
else:
set {_section.sk::single::test} to raw expression of expr-2
set {_section.sk::single::args::*} to extractArgs({_section.sk::single::test})

set {_section.sk::single::code} to expr-1
set {_section.sk::single::code} to join expr-1 with nl
if {_section.sk::single::code} is not set:
return {_none}

# Compile the line into a trigger
set {_section.sk::single::name} to "section"


set {_section.sk::single::event} to new SectionSkriptEvent({_section.sk::single::name}, null)
set {_section.sk::single::trigger} to compile line {_section.sk::single::code} with {_section.sk::single::event} in {_section.sk::single::script}

Expand Down
Loading