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
10 changes: 5 additions & 5 deletions gitgalaxy/standards/language_standards.py
Original file line number Diff line number Diff line change
Expand Up @@ -9742,7 +9742,7 @@ class PrismConfigSchema(TypedDict):
),
# 2. args: Parameters / Coupling. Captures parameters in handlers (on, command, function).
"args": re.compile(
r"(?:on|command|function|getprop|setprop)\s+[a-zA-Z0-9_-]+\s+([^\n]+)",
r"(?:on|command|function|getprop|setprop)\s+[a-zA-Z0-9_-]+\s+((?:(?!--|//|#|/\*)[^\n])+?)(?=[ \t]*(?:--|//|#|/\*|\n|$))",
re.I,
),
# 3. linear: Sequential I/O & Network Boundaries. Structural boundaries and state transformation verbs.
Expand All @@ -9755,7 +9755,7 @@ class PrismConfigSchema(TypedDict):
),
# 4. func_start: Executable Logic Anchors. Anchors executable logic blocks (handlers).
"func_start": re.compile(
r"^[ \t]*(?:private\s+|public[ \t]+)?(?:on|command|function|getprop|setprop)\s+([a-zA-Z0-9_-]+)(?=[ \t\n]|$)",
r"^[ \t]*(?:private[ \t]+|public[ \t]+)?(?:on|command|function|getprop|setprop)[ \t]+([a-zA-Z0-9_-]+)(?=[ \t\n]|--|//|#|/\*|$)",
re.I | re.M,
),
# 5. class_start: Object / Entity Declarations. Defines structural entities (Stacks, Behaviors, Widgets).
Expand All @@ -9772,7 +9772,7 @@ class PrismConfigSchema(TypedDict):
# after would break the same lookahead, so it never actually
# matched anything either).
"class_start": re.compile(
r"^[ \t]*(?:script|behavior|widget|module|library)\s+([a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*){0,10})(?=[ \t\n]|$)",
r"^[ \t]*(?:script|behavior|widget|module|library)[ \t]+([a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*){0,10})(?=[ \t]*(?:--|//|#|/\*|$))",
re.I | re.M,
),
# --- PHASE 2: RISK & STRUCTURAL INTEGRITY ---
Expand Down Expand Up @@ -9817,7 +9817,7 @@ class PrismConfigSchema(TypedDict):
),
# 10. api: Public Surface Area. Exposed surface area (Any non-private handler).
"api": re.compile(
r"^[ \t]*(?:public[ \t]+)?(?!(?:private)\s+)(?:on|command|function|getprop|setprop)\s+[a-zA-Z0-9_-]+",
r"^[ \t]*(?:public[ \t]+)?(?!(?:private)[ \t]+)(?:on|command|function|getprop|setprop)[ \t]+[a-zA-Z0-9_-]+",
re.I | re.M,
),
# 11. flux: State Mutation. State mutation (The 'put into' core of xTalk).
Expand Down Expand Up @@ -9925,7 +9925,7 @@ class PrismConfigSchema(TypedDict):
# 24. import: Dependency Inclusions. Library and stack loading.
"import": re.compile(r"\b(start\s+using\s+(?:stack|behavior)|require|include|module)\b", re.I),
"_dependency_capture": re.compile(
r"^[ \t]*(?:start[ \t\n]+using[ \t\n]+(?:stack[ \t\n]+|behavior[ \t\n]+)?|require[ \t\n]+|include[ \t\n]+|module[ \t\n]+)(?:['\"]([^'\"]+)['\"]|([^'\"\s]+))",
r"^[ \t]*(?:start[ \t]+using[ \t]+(?:stack[ \t]+|behavior[ \t]+)?|require[ \t]+|include[ \t]+|module[ \t]+)(?:['\"]([^'\"]+)['\"]|([^'\"\s]+))",
re.I | re.M,
),
# 25. ownership: Authorship metadata in comments.
Expand Down
184 changes: 184 additions & 0 deletions tests/extraction/languages/test_livecode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
import sys
from pathlib import Path

_EXTRACTION_DIR = str(Path(__file__).resolve().parent.parent)
if _EXTRACTION_DIR not in sys.path:
sys.path.insert(0, _EXTRACTION_DIR)

import pytest # noqa: E402
from _extraction_harness import ( # noqa: E402 # type: ignore
assert_invalid_no_match,
assert_pathological_dependency_match,
assert_pathological_match,
assert_valid_dependency_match,
assert_valid_match,
)

from gitgalaxy.standards.language_standards import LANGUAGE_DEFINITIONS # noqa: E402

LIVECODE_RULES = LANGUAGE_DEFINITIONS["livecode"]["rules"]


def test_livecode_func_start():
valid = [
("on TargetFunc", "TargetFunc"),
("command TargetFunc", "TargetFunc"),
("function TargetFunc", "TargetFunc"),
("getprop TargetFunc", "TargetFunc"),
("setprop TargetFunc", "TargetFunc"),
("private function TargetFunc", "TargetFunc"),
("public command TargetFunc", "TargetFunc"),
("private on TargetFunc", "TargetFunc"),
("public on TargetFunc", "TargetFunc"),
("private getprop TargetFunc", "TargetFunc"),
]

invalid = [
("script TargetFunc", None),
("put TargetFunc into x", None),
("repeat with TargetFunc", None),
("function_not_start = 1", None),
("command_name", None),
('put "on TargetFunc" into x', None),
("on", None),
("function TargetFunc()", None),
]

pathological = [
("private \t command \t TargetFunc \t ", "TargetFunc"),
("public \t function \t TargetFunc", "TargetFunc"),
("public \t function \t TargetFunc", "TargetFunc"),
("on \tTargetFunc\t", "TargetFunc"),
("private\t\tcommand\t\tTargetFunc", "TargetFunc"),
("on TargetFunc--comment", "TargetFunc"),
("command TargetFunc//comment", "TargetFunc"),
("function TargetFunc#comment", "TargetFunc"),
("getprop TargetFunc/*comment*/", "TargetFunc"),
]

for payload, expected in valid:
assert_valid_match(LIVECODE_RULES["func_start"], payload, expected, "livecode.func_start")

for payload, _ in invalid:
assert_invalid_no_match(LIVECODE_RULES["func_start"], payload, "livecode.func_start")

for payload, expected in pathological:
assert_pathological_match(LIVECODE_RULES["func_start"], payload, expected, "livecode.func_start")


def test_livecode_class_start():
valid = [
("script TargetScript", "TargetScript"),
("behavior TargetBehavior", "TargetBehavior"),
("widget TargetWidget", "TargetWidget"),
("module com.livecode.library", "com.livecode.library"),
("library TargetLibrary", "TargetLibrary"),
]

invalid = [
("on script", None),
("put behavior into x", None),
("widget_not_start = 1", None),
('put "script TargetScript" into x', None),
("module ", None),
("script TargetScript pArg", None),
]

pathological = [
("script \t TargetScript", "TargetScript"),
("module \t com.livecode.library", "com.livecode.library"),
("widget \t TargetWidget \t ", "TargetWidget"),
("behavior\t\tTargetBehavior", "TargetBehavior"),
("script TargetScript--comment", "TargetScript"),
("widget TargetWidget//comment", "TargetWidget"),
]

for payload, expected in valid:
assert_valid_match(LIVECODE_RULES["class_start"], payload, expected, "livecode.class_start")

for payload, _ in invalid:
assert_invalid_no_match(LIVECODE_RULES["class_start"], payload, "livecode.class_start")

for payload, expected in pathological:
assert_pathological_match(LIVECODE_RULES["class_start"], payload, expected, "livecode.class_start")


def test_livecode_args():
valid = [
("on TargetFunc pArg1", "pArg1"),
("command TargetFunc pArg1, pArg2", "pArg1, pArg2"),
("function TargetFunc pArg1, pArg2, pArg3", "pArg1, pArg2, pArg3"),
("setprop TargetFunc pArg1", "pArg1"),
("on TargetFunc @pArray", "@pArray"),
]

invalid = [
("on TargetFunc", None),
("command TargetFunc\n", None),
("script TargetScript pArg", None),
("on TargetFunc -- comment", None),
("on TargetFunc // comment", None),
("on TargetFunc # comment", None),
]

pathological = [
("on TargetFunc \t pArg1, pArg2", "pArg1, pArg2"),
("command TargetFunc pArg1, pArg2 -- comment", "pArg1, pArg2"),
("function TargetFunc pArg1 // comment", "pArg1"),
("setprop TargetFunc pArg # comment", "pArg"),
("on TargetFunc pArg /* comment */", "pArg"),
]

for payload, expected in valid:
assert_valid_match(LIVECODE_RULES["args"], payload, expected, "livecode.args")

for payload, _ in invalid:
assert_invalid_no_match(LIVECODE_RULES["args"], payload, "livecode.args")

for payload, expected in pathological:
assert_pathological_match(LIVECODE_RULES["args"], payload, expected, "livecode.args")


def test_livecode_dependency_capture():
valid = [
('start using stack "lib"', "lib"),
('require "database"', "database"),
('include "my_lib"', "my_lib"),
('module "com.livecode.math"', "com.livecode.math"),
("start using behavior my_behavior", "my_behavior"),
('start using "stack_name"', "stack_name"),
("start using stack my_stack", "my_stack"),
]

invalid = [
("put empty into requirePath", None),
("require_login", None),
]

xfail_invalid = [
('/*\nstart using stack "fake"\n*/', None),
('put "\nstart using stack \\"fake\\"\n" into x', None),
]

pathological = [
('start \t using \t behavior \t "btnBehavior"', "btnBehavior"),
('start \t using \t stack \t "lib"', "lib"),
('require \t "database"', "database"),
('module \t "com.livecode.math"', "com.livecode.math"),
]

for payload, expected in valid:
assert_valid_dependency_match(
LIVECODE_RULES["_dependency_capture"], payload, expected, "livecode._dependency_capture"
)

for payload, _ in invalid:
assert_invalid_no_match(LIVECODE_RULES["_dependency_capture"], payload, "livecode._dependency_capture")

for payload, _ in xfail_invalid:
pytest.param(payload, None, marks=pytest.mark.xfail(reason="No block shielding"))

for payload, expected in pathological:
assert_pathological_dependency_match(
LIVECODE_RULES["_dependency_capture"], payload, expected, "livecode._dependency_capture"
)
14 changes: 1 addition & 13 deletions tests/extraction/test_dependency_extraction_strict.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest

from gitgalaxy.standards.language_standards import LANGUAGE_DEFINITIONS

# =======================================================================# THE GRAVITY LINK GAUNTLET
Expand Down Expand Up @@ -40,7 +41,6 @@
)
],
},

"html": {
"valid": [
('<script src="app.js"></script>', "app.js"),
Expand All @@ -65,9 +65,6 @@
"invalid": ["CHARACTER(LEN=10) :: INCLUDE_FILE"],
"pathological": [("USE \n , \n INTRINSIC \n :: \n omp_lib", "omp_lib")],
},



"dart": {
"valid": [
("import 'dart:io';", "dart:io"),
Expand All @@ -92,15 +89,6 @@
"invalid": ["ENV FROM_PATH=/app"],
"pathological": [("FROM \n --platform=linux/amd64 \n alpine:3.18", "alpine:3.18")],
},

"livecode": {
"valid": [
('start using stack "lib"', "lib"),
('require "database"', "database"),
],
"invalid": ["put empty into requirePath"],
"pathological": [('start \n using \n behavior \n "btnBehavior"', "btnBehavior")],
},
"objective-c": {
"valid": [
("#import <Foundation/Foundation.h>", "Foundation/Foundation.h"),
Expand Down
13 changes: 0 additions & 13 deletions tests/extraction/test_function_extraction_strict.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,17 +96,6 @@
],
},

"livecode": {
"valid": [
("on TargetFunc", "TargetFunc"),
("command TargetFunc", "TargetFunc"),
("private function TargetFunc", "TargetFunc"),
],
"invalid": ["script TargetFunc", "put TargetFunc", "repeat with TargetFunc"],
"pathological": [("private \n command \n TargetFunc \n ", "TargetFunc")],
},


"dockerfile": {
"valid": [
("RUN apt-get update", "RUN"),
Expand All @@ -130,8 +119,6 @@
"invalid": ["//TargetFunc DD DSN=", "//* TargetFunc EXEC"],
"pathological": [("//TargetFunc \t EXEC ", "TargetFunc")],
},


"css": {
"valid": [("@media (max-width: 600px) {", "@media"), ("@keyframes TargetFunc {", "@keyframes")],
"invalid": [".TargetFunc {", "#TargetFunc {"],
Expand Down
Loading