**refactor(dynamic): introduce framework-specific fallback logic for Quartz, Spring, Celery, Django, Express, and Socket.IO, enhance middleware/request handling and extend test coverage**

This commit is contained in:
elipeter 2026-05-27 12:30:24 -05:00
parent a12f7efc3a
commit 8eeb9590b4
6 changed files with 554 additions and 54 deletions

View file

@ -4457,6 +4457,9 @@ public class NyxHarness {{
System.out.println("__NYX_SINK_HIT__");
try {{
Class<?> cls = Class.forName({entry_class:?});
if (nyxTryQuartz(cls, payload)) {{
return;
}}
Constructor<?> ctor = cls.getDeclaredConstructor();
ctor.setAccessible(true);
Object instance = ctor.newInstance();
@ -4469,6 +4472,9 @@ public class NyxHarness {{
System.exit(78);
}}
m.setAccessible(true);
if (nyxTrySpringHandlerInterceptor(instance, m, payload)) {{
return;
}}
Class<?>[] params = m.getParameterTypes();
Object[] mArgs = new Object[params.length];
for (int i = 0; i < params.length; i++) {{
@ -4493,6 +4499,50 @@ public class NyxHarness {{
}}
return "";
}}
static boolean nyxTryQuartz(Class<?> cls, String payload) {{
try {{
Class<?> jobClass = Class.forName("org.quartz.Job");
if (!jobClass.isAssignableFrom(cls)) {{
return false;
}}
System.setProperty("org.quartz.scheduler.skipUpdateCheck", "true");
System.setProperty("org.quartz.threadPool.threadCount", "1");
Class<?> jobBuilderClass = Class.forName("org.quartz.JobBuilder");
Object jobBuilder = jobBuilderClass.getMethod("newJob", Class.class)
.invoke(null, cls.asSubclass(jobClass));
jobBuilder = jobBuilder.getClass().getMethod("withIdentity", String.class)
.invoke(jobBuilder, "nyx-job");
jobBuilder = jobBuilder.getClass().getMethod("usingJobData", String.class, String.class)
.invoke(jobBuilder, "payload", payload);
Object jobDetail = jobBuilder.getClass().getMethod("build").invoke(jobBuilder);
Class<?> triggerBuilderClass = Class.forName("org.quartz.TriggerBuilder");
Object triggerBuilder = triggerBuilderClass.getMethod("newTrigger").invoke(null);
triggerBuilder = triggerBuilder.getClass().getMethod("withIdentity", String.class)
.invoke(triggerBuilder, "nyx-trigger");
triggerBuilder = triggerBuilder.getClass().getMethod("startNow").invoke(triggerBuilder);
Object trigger = triggerBuilder.getClass().getMethod("build").invoke(triggerBuilder);
Object scheduler = Class.forName("org.quartz.impl.StdSchedulerFactory")
.getMethod("getDefaultScheduler")
.invoke(null);
Class<?> schedulerClass = Class.forName("org.quartz.Scheduler");
Class<?> jobDetailClass = Class.forName("org.quartz.JobDetail");
Class<?> triggerClass = Class.forName("org.quartz.Trigger");
schedulerClass.getMethod("start").invoke(scheduler);
schedulerClass.getMethod("scheduleJob", jobDetailClass, triggerClass)
.invoke(scheduler, jobDetail, trigger);
schedulerClass.getMethod("shutdown", boolean.class).invoke(scheduler, true);
return true;
}} catch (ClassNotFoundException missingQuartz) {{
return false;
}} catch (Throwable e) {{
System.err.println("NYX_QUARTZ_FALLBACK: " + e.getClass().getName() + ": " + e.getMessage());
return false;
}}
}}
}}
"#,
entry_class = entry_class,
@ -4506,7 +4556,7 @@ public class NyxHarness {{
command: vec![
"java".to_owned(),
"-cp".to_owned(),
".".to_owned(),
".:lib/*".to_owned(),
"NyxHarness".to_owned(),
],
extra_files: framework_dependency_files(spec),
@ -4569,6 +4619,69 @@ public class NyxHarness {{
}}
return "";
}}
static boolean nyxTrySpringHandlerInterceptor(Object instance, Method m, String payload) {{
Class<?>[] params = m.getParameterTypes();
if (params.length < 3 || !m.getName().equals("preHandle")) {{
return false;
}}
try {{
Object[] args = new Object[params.length];
for (int i = 0; i < params.length; i++) {{
String name = params[i].getName();
if (name.endsWith("HttpServletRequest")) {{
args[i] = nyxServletProxy(params[i], payload);
}} else if (name.endsWith("HttpServletResponse")) {{
args[i] = nyxServletProxy(params[i], payload);
}} else if (params[i].equals(String.class)) {{
args[i] = payload;
}} else {{
args[i] = new Object();
}}
}}
m.invoke(instance, args);
return true;
}} catch (InvocationTargetException ite) {{
Throwable cause = ite.getCause() == null ? ite : ite.getCause();
System.err.println("NYX_SPRING_INTERCEPTOR_FALLBACK: " + cause.getClass().getName() + ": " + cause.getMessage());
return false;
}} catch (Throwable e) {{
System.err.println("NYX_SPRING_INTERCEPTOR_FALLBACK: " + e.getClass().getName() + ": " + e.getMessage());
return false;
}}
}}
static Object nyxServletProxy(Class<?> iface, String payload) {{
if (!iface.isInterface()) {{
return null;
}}
return java.lang.reflect.Proxy.newProxyInstance(
iface.getClassLoader(),
new Class<?>[] {{ iface }},
(proxy, method, args) -> {{
String name = method.getName();
if (name.equals("getParameter")) return payload;
if (name.equals("getQueryString")) return "q=" + java.net.URLEncoder.encode(payload, java.nio.charset.StandardCharsets.UTF_8);
if (name.equals("getRequestURI")) return "/nyx";
if (name.equals("getRequestURL")) return new StringBuffer("http://localhost/nyx");
if (name.equals("getMethod")) return "POST";
if (name.equals("getHeader")) return null;
if (name.equals("getWriter")) return new java.io.PrintWriter(System.out, true);
if (name.equals("toString")) return "NyxServletProxy(" + iface.getName() + ")";
Class<?> ret = method.getReturnType();
if (!ret.isPrimitive()) return null;
if (ret.equals(boolean.class)) return false;
if (ret.equals(byte.class)) return (byte) 0;
if (ret.equals(short.class)) return (short) 0;
if (ret.equals(int.class)) return 0;
if (ret.equals(long.class)) return 0L;
if (ret.equals(float.class)) return 0.0f;
if (ret.equals(double.class)) return 0.0d;
if (ret.equals(char.class)) return '\0';
return null;
}}
);
}}
}}
"#,
entry_class = entry_class,
@ -4582,7 +4695,7 @@ public class NyxHarness {{
command: vec![
"java".to_owned(),
"-cp".to_owned(),
".".to_owned(),
".:lib/*".to_owned(),
"NyxHarness".to_owned(),
],
extra_files: framework_dependency_files(spec),

View file

@ -1095,8 +1095,39 @@ if (_h == null) {{
process.stderr.write('NYX_HANDLER_NOT_FOUND: ' + {handler:?} + '\n');
process.exit(78);
}}
async function _nyxTryNodeCron(schedule, handler) {{
let cron;
try {{
cron = require('node-cron');
}} catch (_) {{
return false;
}}
try {{
if (typeof cron.validate === 'function' && !cron.validate(schedule)) return false;
let ran = false;
let task = cron.schedule(schedule, async function () {{
ran = true;
const value = await Promise.resolve(handler(payload));
if (value != null) process.stdout.write(String(value) + '\n');
return value;
}}, {{ scheduled: false }});
if (task && typeof task.execute === 'function') {{
await Promise.resolve(task.execute());
if (task && typeof task.stop === 'function') task.stop();
if (task && typeof task.destroy === 'function') task.destroy();
return ran;
}}
if (task && typeof task.stop === 'function') task.stop();
if (task && typeof task.destroy === 'function') task.destroy();
return false;
}} catch (e) {{
process.stderr.write('NYX_NODE_CRON_FALLBACK: ' + (e && e.message ? e.message : String(e)) + '\n');
return false;
}}
}}
(async () => {{
try {{
if (await _nyxTryNodeCron({schedule:?}, _h)) return;
const _result = await Promise.resolve(_h(payload));
if (_result != null) process.stdout.write(String(_result) + '\n');
}} catch (e) {{
@ -1134,8 +1165,48 @@ if (_h == null) {{
process.stderr.write('NYX_RESOLVER_NOT_FOUND: ' + {handler:?} + '\n');
process.exit(78);
}}
async function _nyxTryGraphqlJs(typeName, fieldName, resolver) {{
let graphql;
let buildSchema;
try {{
const gql = require('graphql');
graphql = gql.graphql;
buildSchema = gql.buildSchema;
}} catch (_) {{
return false;
}}
const safeField = /^[A-Za-z_][A-Za-z0-9_]*$/.test(fieldName) ? fieldName : 'nyxField';
try {{
const schema = buildSchema('type Query {{ ' + safeField + '(id: String, input: String): String }}');
const rootValue = {{}};
rootValue[safeField] = async function (args, context, info) {{
const value = await Promise.resolve(resolver(
null,
{{ id: payload, input: payload, value: payload }},
context || {{}},
info || {{ fieldName: safeField, parentType: typeName }}
));
return value == null ? null : String(value);
}};
const result = await graphql({{
schema,
source: 'query($value: String) {{ ' + safeField + '(id: $value) }}',
rootValue,
variableValues: {{ value: payload }},
}});
if (result.errors && result.errors.length) return false;
if (result.data && result.data[safeField] != null) {{
process.stdout.write(String(result.data[safeField]) + '\n');
}}
return true;
}} catch (e) {{
process.stderr.write('NYX_GRAPHQL_JS_FALLBACK: ' + (e && e.message ? e.message : String(e)) + '\n');
return false;
}}
}}
(async () => {{
try {{
if (await _nyxTryGraphqlJs({type_name:?}, {field:?}, _h)) return;
// Apollo resolver shape: (parent, args, context, info).
const _info = {{ fieldName: {field:?}, parentType: {type_name:?} }};
const _result = await Promise.resolve(_h(null, {{ id: payload, input: payload }}, {{}}, _info));
@ -1171,8 +1242,48 @@ if (_h == null) {{
process.stderr.write('NYX_HANDLER_NOT_FOUND: ' + {handler:?} + '\n');
process.exit(78);
}}
async function _nyxTryWs(handler) {{
let Ws;
try {{
Ws = require('ws');
}} catch (_) {{
return false;
}}
try {{
const events = require('events');
const Server = Ws.WebSocketServer || Ws.Server;
if (!Server) return false;
const wss = new Server({{ noServer: true }});
const pending = [];
let delivered = false;
wss.on('connection', (socket) => {{
socket.on('message', (data, isBinary) => {{
delivered = true;
pending.push(Promise.resolve(handler(data, isBinary)).then((result) => {{
if (result != null) process.stdout.write(String(result) + '\n');
}}));
}});
}});
const socket = new events.EventEmitter();
socket.readyState = Ws.OPEN || 1;
socket.send = (data) => {{
if (data != null) process.stdout.write(String(data) + '\n');
}};
socket.close = () => {{}};
wss.emit('connection', socket, {{ url: {path:?}, headers: {{}} }});
socket.emit('message', Buffer.from(String(payload), 'utf8'), false);
await Promise.all(pending);
if (typeof wss.close === 'function') wss.close();
return delivered;
}} catch (_) {{
return false;
}}
}}
(async () => {{
try {{
if (await _nyxTryWs(_h)) {{
return;
}}
// ws library: handler(message); socket.io: handler(socket, data).
let _result;
try {{
@ -1217,8 +1328,62 @@ if (_h == null) {{
}}
const _req = {{ body: payload, query: {{ q: payload }}, params: {{ id: payload }}, headers: {{}}, method: 'POST', url: '/nyx' }};
const _res = {{ statusCode: 200, headers: {{}}, end: function(d){{ if (d != null) process.stdout.write(String(d) + '\n'); }}, setHeader: function(k, v){{ this.headers[k] = v; }} }};
async function _nyxTryExpressMiddleware(handler) {{
let express;
try {{
express = require('express');
}} catch (_) {{
return false;
}}
try {{
const stream = require('stream');
const app = express();
app.use(express.text({{ type: '*/*' }}));
app.use(handler);
const req = new stream.Readable({{
read() {{
this.push(Buffer.from(String(payload), 'utf8'));
this.push(null);
}},
}});
req.method = 'POST';
req.url = '/nyx?q=' + encodeURIComponent(String(payload));
req.headers = {{
host: 'localhost',
'content-type': 'text/plain',
'content-length': Buffer.byteLength(String(payload), 'utf8'),
}};
const chunks = [];
await new Promise((resolve) => {{
const res = new stream.Writable({{
write(chunk, _enc, cb) {{
chunks.push(Buffer.from(chunk));
cb();
}},
}});
res.statusCode = 200;
res.headers = {{}};
res.setHeader = function (k, v) {{ this.headers[String(k).toLowerCase()] = v; }};
res.getHeader = function (k) {{ return this.headers[String(k).toLowerCase()]; }};
res.end = function (chunk) {{
if (chunk != null) chunks.push(Buffer.from(String(chunk)));
resolve();
}};
app.handle(req, res, function (err) {{
if (err) process.stderr.write('NYX_EXPRESS_NEXT_ERR: ' + err + '\n');
resolve();
}});
}});
if (chunks.length > 0) process.stdout.write(Buffer.concat(chunks).toString('utf8') + '\n');
return true;
}} catch (e) {{
process.stderr.write('NYX_EXPRESS_MIDDLEWARE_FALLBACK: ' + (e && e.message ? e.message : String(e)) + '\n');
return false;
}}
}}
(async () => {{
try {{
if (await _nyxTryExpressMiddleware(_h)) return;
const _result = await Promise.resolve(_h(_req, _res, function(_e){{ if (_e) process.stderr.write('NYX_NEXT_ERR: ' + _e + '\n'); }}));
if (_result != null) process.stdout.write(String(_result) + '\n');
}} catch (e) {{

View file

@ -3116,11 +3116,23 @@ fn emit_middleware_harness(spec: &HarnessSpec, name: &str) -> HarnessSource {
r#"{preamble}
echo "__NYX_MIDDLEWARE__: " . {name:?} . "\n";
$req = new stdClass();
$req->body = $payload;
$req->path = '/nyx';
$req->method = 'POST';
$req->query = [ 'q' => $payload ];
function __nyx_make_middleware_request(string $payload) {{
if (class_exists('Illuminate\\Http\\Request')) {{
try {{
return Illuminate\Http\Request::create('/nyx', 'POST', ['q' => $payload], [], [], [], $payload);
}} catch (Throwable $e) {{
fwrite(STDERR, 'NYX_LARAVEL_REQUEST_FALLBACK: ' . get_class($e) . ': ' . $e->getMessage() . "\n");
}}
}}
$req = new stdClass();
$req->body = $payload;
$req->path = '/nyx';
$req->method = 'POST';
$req->query = [ 'q' => $payload ];
return $req;
}}
$req = __nyx_make_middleware_request($payload);
$next = function ($r) {{ return $r; }};
if (class_exists({handler:?})) {{

View file

@ -1299,13 +1299,40 @@ _h = getattr(_entry_mod, {handler:?}, None)
if _h is None:
print("NYX_HANDLER_NOT_FOUND: " + {handler:?}, file=sys.stderr, flush=True)
sys.exit(78)
def _nyx_try_celery_eager(task, body):
try:
import celery # noqa: F401
except Exception:
return False
if not hasattr(task, "apply"):
return False
try:
app = getattr(task, "app", None)
if app is not None and hasattr(app, "conf"):
try:
app.conf.task_always_eager = True
app.conf.task_eager_propagates = False
except Exception:
pass
_result = task.apply(args=(body,), throw=False)
_value = getattr(_result, "result", None)
if _value is not None:
print(str(_value), flush=True)
return True
except SystemExit:
raise
except Exception as _e:
print(f"NYX_CELERY_EAGER_FALLBACK: {{type(_e).__name__}}: {{_e}}", file=sys.stderr, flush=True)
return False
try:
_result = _h(payload)
if _result is not None:
try:
print(str(_result), flush=True)
except Exception:
pass
if not _nyx_try_celery_eager(_h, payload):
_result = _h(payload)
if _result is not None:
try:
print(str(_result), flush=True)
except Exception:
pass
except SystemExit as _e:
sys.exit(_e.code)
except Exception as _e:
@ -1345,16 +1372,61 @@ if _resolver is None:
print("NYX_RESOLVER_NOT_FOUND: " + {handler:?}, file=sys.stderr, flush=True)
sys.exit(78)
try:
# Graphene resolvers are `resolve_field(self, info, **args)`; we
# synthesise `self = None`, `info = _NyxGraphQLInfo`, and pass the
# payload positionally so a `def resolve_foo(self, info, id):` shape
# binds `id = payload`.
_result = _resolver(None, _NyxGraphQLInfo({field:?}), payload)
if _result is not None:
def _nyx_try_graphene(resolver, type_name, field_name, body):
try:
print(str(_result), flush=True)
import graphene
except Exception:
pass
return False
safe_field = "".join(ch if (ch.isalnum() or ch == "_") else "_" for ch in str(field_name))
if not safe_field or safe_field[0].isdigit():
safe_field = "nyx_" + safe_field
resolver_name = "resolve_" + safe_field
try:
def _nyx_resolve(root, info, id=None, input=None, **kwargs):
arg = id if id is not None else (input if input is not None else body)
try:
return resolver(root, info, arg)
except TypeError:
try:
return resolver(info, arg)
except TypeError:
return resolver(root, info, **{{safe_field: arg}})
Query = type(
"NyxDynamicQuery",
(graphene.ObjectType,),
{{
safe_field: graphene.String(id=graphene.String(), input=graphene.String()),
resolver_name: _nyx_resolve,
}},
)
schema = graphene.Schema(query=Query)
query = "query($value: String) {{ " + safe_field + "(id: $value) }}"
result = schema.execute(query, variable_values={{"value": body}})
if getattr(result, "errors", None):
return False
data = getattr(result, "data", None) or {{}}
value = data.get(safe_field)
if value is not None:
print(str(value), flush=True)
return True
except SystemExit:
raise
except Exception as _e:
print(f"NYX_GRAPHENE_FALLBACK: {{type(_e).__name__}}: {{_e}}", file=sys.stderr, flush=True)
return False
if not _nyx_try_graphene(_resolver, {type_name:?}, {field:?}, payload):
# Graphene resolvers are `resolve_field(self, info, **args)`; we
# synthesise `self = None`, `info = _NyxGraphQLInfo`, and pass the
# payload positionally so a `def resolve_foo(self, info, id):` shape
# binds `id = payload`.
_result = _resolver(None, _NyxGraphQLInfo({field:?}), payload)
if _result is not None:
try:
print(str(_result), flush=True)
except Exception:
pass
except SystemExit as _e:
sys.exit(_e.code)
except TypeError:
@ -1396,21 +1468,40 @@ if _h is None:
print("NYX_HANDLER_NOT_FOUND: " + {handler:?}, file=sys.stderr, flush=True)
sys.exit(78)
try:
# python-socketio handlers are `def message(sid, data)`; Channels
# consumers are `def receive(self, text_data=None, bytes_data=None)`.
# Try (sid, payload) first, then fall back to (payload).
try:
_result = _h("nyx-sid", payload)
except TypeError:
def _nyx_try_socketio(handler_name, handler, body):
try:
_result = _h(payload)
except TypeError:
_result = _h(None, payload)
if _result is not None:
try:
print(str(_result), flush=True)
import socketio
except Exception:
pass
return False
try:
server = socketio.Server(async_mode="threading")
server.on(handler_name, handler=handler, namespace="/")
result = server._trigger_event(handler_name, "/", "nyx-sid", body)
if result is not None:
print(str(result), flush=True)
return True
except SystemExit:
raise
except Exception as _e:
print(f"NYX_SOCKETIO_FALLBACK: {{type(_e).__name__}}: {{_e}}", file=sys.stderr, flush=True)
return False
if not _nyx_try_socketio({handler:?}, _h, payload):
# python-socketio handlers are `def message(sid, data)`; Channels
# consumers are `def receive(self, text_data=None, bytes_data=None)`.
# Try (sid, payload) first, then fall back to (payload).
try:
_result = _h("nyx-sid", payload)
except TypeError:
try:
_result = _h(payload)
except TypeError:
_result = _h(None, payload)
if _result is not None:
try:
print(str(_result), flush=True)
except Exception:
pass
except SystemExit as _e:
sys.exit(_e.code)
except Exception as _e:
@ -1454,19 +1545,63 @@ if _h is None:
print("NYX_HANDLER_NOT_FOUND: " + {handler:?}, file=sys.stderr, flush=True)
sys.exit(78)
try:
_req = _NyxRequest(payload)
# Try class-shaped middleware (instantiate with a get_response stub).
try:
_mw = _h(lambda r: r)
_result = _mw(_req)
except TypeError:
# Method on an existing class instance.
_result = _h(_req)
if _result is not None:
def _nyx_try_django_middleware(factory, body):
try:
print(str(_result), flush=True)
from django.conf import settings
if not settings.configured:
settings.configure(
DEFAULT_CHARSET="utf-8",
SECRET_KEY="nyx-dynamic-harness",
ROOT_URLCONF=__name__,
ALLOWED_HOSTS=["testserver", "localhost", "127.0.0.1"],
INSTALLED_APPS=[],
MIDDLEWARE=[],
)
import django
django.setup()
from django.test import RequestFactory
except Exception:
pass
return False
try:
request = RequestFactory().post("/nyx", data={{"q": body}})
request._body = str(body).encode("utf-8", "replace")
try:
mw = factory(lambda req: req)
result = mw(request)
except TypeError:
try:
instance = factory()
if hasattr(instance, "process_request"):
result = instance.process_request(request)
elif callable(instance):
result = instance(request)
else:
return False
except TypeError:
result = factory(request)
if result is not None:
print(str(result), flush=True)
return True
except SystemExit:
raise
except Exception as _e:
print(f"NYX_DJANGO_MIDDLEWARE_FALLBACK: {{type(_e).__name__}}: {{_e}}", file=sys.stderr, flush=True)
return False
if not _nyx_try_django_middleware(_h, payload):
_req = _NyxRequest(payload)
# Try class-shaped middleware (instantiate with a get_response stub).
try:
_mw = _h(lambda r: r)
_result = _mw(_req)
except TypeError:
# Method on an existing class instance.
_result = _h(_req)
if _result is not None:
try:
print(str(_result), flush=True)
except Exception:
pass
except SystemExit as _e:
sys.exit(_e.code)
except Exception as _e:

View file

@ -760,7 +760,19 @@ puts "__NYX_SCHEDULED_JOB__: " + {sched:?}
target = nil
if Object.const_defined?({handler:?})
begin
target = Object.const_get({handler:?}).new
cls = Object.const_get({handler:?})
begin
require 'sidekiq/testing'
if cls.respond_to?(:perform_async)
Sidekiq::Testing.inline! do
cls.perform_async($nyx_payload)
end
exit 0
end
rescue LoadError, StandardError => e
STDERR.puts("NYX_SIDEKIQ_INLINE_FALLBACK: #{{e.class.name}}: #{{e.message}}") if ENV['NYX_DEBUG']
end
target = cls.new
if target.respond_to?(:perform)
begin
result = target.perform($nyx_payload)
@ -859,17 +871,53 @@ puts "__NYX_MIDDLEWARE__: " + {name:?}
require 'stringio'
# Rack-shape middleware: class with #call(env).
env = {{
'REQUEST_METHOD' => 'POST',
'PATH_INFO' => '/nyx',
'QUERY_STRING' => "q=#{{$nyx_payload}}",
'rack.input' => StringIO.new($nyx_payload),
'nyx.payload' => $nyx_payload,
}}
def nyx_middleware_env
{{
'REQUEST_METHOD' => 'POST',
'PATH_INFO' => '/nyx',
'QUERY_STRING' => "q=#{{$nyx_payload}}",
'rack.input' => StringIO.new($nyx_payload),
'nyx.payload' => $nyx_payload,
}}
end
def nyx_try_rack_middleware(cls)
begin
require 'rack/mock'
rescue LoadError
return false
end
begin
terminal = lambda {{ |_env| [200, {{ 'content-type' => 'text/plain' }}, ['ok']] }}
middleware = begin
cls.new(terminal)
rescue ArgumentError
cls.new
end
return false unless middleware.respond_to?(:call)
app = lambda do |env|
env['nyx.payload'] = $nyx_payload
middleware.call(env)
end
response = Rack::MockRequest.new(app).request(
'POST',
'/nyx?q=' + Rack::Utils.escape($nyx_payload.to_s),
input: $nyx_payload
)
print(response.body.to_s) if response && response.respond_to?(:body) && !response.body.to_s.empty?
true
rescue StandardError => e
STDERR.puts("NYX_EXCEPTION: #{{e.class.name}}: #{{e.message}}")
false
end
end
env = nyx_middleware_env
# Rack-shape middleware: class with #call(env).
if Object.const_defined?({handler:?})
cls = Object.const_get({handler:?})
exit 0 if nyx_try_rack_middleware(cls)
begin
inst = cls.new(lambda {{ |e| [200, {{}}, ['ok']] }})
if inst.respond_to?(:call)

View file

@ -667,6 +667,8 @@ fn scheduled_job_python_harness_carries_sentinel_and_handler() {
assert!(h.source.contains("__NYX_SCHEDULED_JOB__"));
assert!(h.source.contains("\"tick\""));
assert!(h.source.contains("*/5 * * * *"));
assert!(h.source.contains("_nyx_try_celery_eager"));
assert!(h.source.contains("task.apply"));
}
#[test]
@ -682,6 +684,8 @@ fn scheduled_job_js_harness_carries_sentinel_and_handler() {
let h = lang::emit(&spec).expect("emit ok");
assert!(h.source.contains("__NYX_SCHEDULED_JOB__"));
assert!(h.source.contains("\"tick\""));
assert!(h.source.contains("_nyxTryNodeCron"));
assert!(h.source.contains("require('node-cron')"));
}
#[test]
@ -695,6 +699,9 @@ fn scheduled_job_java_harness_carries_sentinel_and_handler() {
let h = lang::emit(&spec).expect("emit ok");
assert!(h.source.contains("__NYX_SCHEDULED_JOB__"));
assert!(h.source.contains("\"execute\""));
assert!(h.source.contains("nyxTryQuartz"));
assert!(h.source.contains("org.quartz.JobBuilder"));
assert_eq!(h.command, vec!["java", "-cp", ".:lib/*", "NyxHarness"]);
}
#[test]
@ -708,6 +715,8 @@ fn scheduled_job_ruby_harness_carries_sentinel_and_handler() {
let h = lang::emit(&spec).expect("emit ok");
assert!(h.source.contains("__NYX_SCHEDULED_JOB__"));
assert!(h.source.contains("TickWorker"));
assert!(h.source.contains("sidekiq/testing"));
assert!(h.source.contains("perform_async"));
}
#[test]
@ -725,6 +734,8 @@ fn graphql_resolver_python_harness_carries_sentinel_and_field() {
assert!(h.source.contains("__NYX_GRAPHQL_RESOLVER__"));
assert!(h.source.contains("\"resolve_user\""));
assert!(h.source.contains("\"Query\""));
assert!(h.source.contains("_nyx_try_graphene"));
assert!(h.source.contains("graphene.Schema"));
}
#[test]
@ -741,6 +752,8 @@ fn graphql_resolver_js_harness_carries_sentinel_and_field() {
let h = lang::emit(&spec).expect("emit ok");
assert!(h.source.contains("__NYX_GRAPHQL_RESOLVER__"));
assert!(h.source.contains("\"resolveUser\""));
assert!(h.source.contains("_nyxTryGraphqlJs"));
assert!(h.source.contains("require('graphql')"));
}
#[test]
@ -790,6 +803,8 @@ fn websocket_python_harness_carries_sentinel_and_handler() {
assert!(h.source.contains("__NYX_WEBSOCKET__"));
assert!(h.source.contains("\"message\""));
assert!(h.source.contains("/ws/chat"));
assert!(h.source.contains("_nyx_try_socketio"));
assert!(h.source.contains("socketio.Server"));
}
#[test]
@ -805,6 +820,8 @@ fn websocket_js_harness_carries_sentinel_and_handler() {
let h = lang::emit(&spec).expect("emit ok");
assert!(h.source.contains("__NYX_WEBSOCKET__"));
assert!(h.source.contains("\"onMessage\""));
assert!(h.source.contains("_nyxTryWs"));
assert!(h.source.contains("require('ws')"));
}
#[test]
@ -835,6 +852,8 @@ fn middleware_python_harness_carries_sentinel_and_handler() {
let h = lang::emit(&spec).expect("emit ok");
assert!(h.source.contains("__NYX_MIDDLEWARE__"));
assert!(h.source.contains("\"audit\""));
assert!(h.source.contains("_nyx_try_django_middleware"));
assert!(h.source.contains("RequestFactory"));
}
#[test]
@ -850,6 +869,8 @@ fn middleware_js_harness_carries_sentinel_and_handler() {
let h = lang::emit(&spec).expect("emit ok");
assert!(h.source.contains("__NYX_MIDDLEWARE__"));
assert!(h.source.contains("\"audit\""));
assert!(h.source.contains("_nyxTryExpressMiddleware"));
assert!(h.source.contains("require('express')"));
}
#[test]
@ -865,6 +886,8 @@ fn middleware_java_harness_carries_sentinel_and_handler() {
let h = lang::emit(&spec).expect("emit ok");
assert!(h.source.contains("__NYX_MIDDLEWARE__"));
assert!(h.source.contains("\"preHandle\""));
assert!(h.source.contains("nyxTrySpringHandlerInterceptor"));
assert!(h.source.contains("HttpServletRequest"));
}
#[test]
@ -880,6 +903,8 @@ fn middleware_ruby_harness_carries_sentinel_and_handler() {
let h = lang::emit(&spec).expect("emit ok");
assert!(h.source.contains("__NYX_MIDDLEWARE__"));
assert!(h.source.contains("AuditMiddleware"));
assert!(h.source.contains("nyx_try_rack_middleware"));
assert!(h.source.contains("Rack::MockRequest"));
}
#[test]
@ -895,6 +920,8 @@ fn middleware_php_harness_carries_sentinel_and_handler() {
let h = lang::emit(&spec).expect("emit ok");
assert!(h.source.contains("__NYX_MIDDLEWARE__"));
assert!(h.source.contains("Audit"));
assert!(h.source.contains("Illuminate\\Http\\Request"));
assert!(h.source.contains("__nyx_make_middleware_request"));
}
#[test]