mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-18 17:16:46 +03:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8769bd4926 |
@@ -495,7 +495,6 @@ re!(
|
|||||||
format!("border(?:Left|Right){WS}*[:=]{WS}*[\"'`]({D}+)px{WS}+solid")
|
format!("border(?:Left|Right){WS}*[:=]{WS}*[\"'`]({D}+)px{WS}+solid")
|
||||||
);
|
);
|
||||||
re!(BORDER_ACCENT_TW_RE, format!("{B}border-[tb]-({D}+){B}"));
|
re!(BORDER_ACCENT_TW_RE, format!("{B}border-[tb]-({D}+){B}"));
|
||||||
re!(ANIMATE_SPIN_RE, format!("{B}animate-spin{B}"));
|
|
||||||
re!(
|
re!(
|
||||||
BORDER_ACCENT_CSS_RE,
|
BORDER_ACCENT_CSS_RE,
|
||||||
format!(
|
format!(
|
||||||
@@ -868,12 +867,7 @@ pub static REGEX_MATCHERS: Lazy<Vec<Matcher>> = Lazy::new(|| {
|
|||||||
Matcher {
|
Matcher {
|
||||||
id: "border-accent-on-rounded",
|
id: "border-accent-on-rounded",
|
||||||
find_all: |l| all(&BORDER_ACCENT_TW_RE, l),
|
find_all: |l| all(&BORDER_ACCENT_TW_RE, l),
|
||||||
test: |m, line| {
|
test: |m, line| has_rounded(line) && num(m.g(1)) >= 1.0,
|
||||||
let scope = containing_markup_tag(line)(m.index);
|
|
||||||
has_rounded(&scope)
|
|
||||||
&& num(m.g(1)) >= 1.0
|
|
||||||
&& !ANIMATE_SPIN_RE.is_match(&scope)
|
|
||||||
},
|
|
||||||
fmt: |m, _| m.whole().to_string(),
|
fmt: |m, _| m.whole().to_string(),
|
||||||
},
|
},
|
||||||
Matcher {
|
Matcher {
|
||||||
@@ -1463,27 +1457,6 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn border_accent_skips_tailwind_spinner() {
|
|
||||||
let g = |line: &str| run("border-accent-on-rounded", line);
|
|
||||||
assert_eq!(
|
|
||||||
g(r#"<div className="rounded-lg border-t-4 border-blue-500" />"#),
|
|
||||||
vec!["border-t-4"]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
g(r#"<div className="rounded-full border-b-2" />"#),
|
|
||||||
vec!["border-b-2"]
|
|
||||||
);
|
|
||||||
assert!(g(r#"<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-accent" />"#).is_empty());
|
|
||||||
assert!(g(r#"<div className="sm:animate-spin rounded-full h-8 w-8 border-t-2" />"#).is_empty());
|
|
||||||
assert!(g(r#"<div className="motion-safe:animate-spin rounded-full border-b-2" />"#).is_empty());
|
|
||||||
assert_eq!(
|
|
||||||
g(r#"<div className="animate-spin rounded-full h-12 w-12 border-b-2" /><div className="rounded-lg border-t-4" />"#),
|
|
||||||
vec!["border-t-4"]
|
|
||||||
);
|
|
||||||
assert!(g(r#"<div className="animate-spin rounded-full h-12 w-12 border-b-2" /><div className="border-t-4" />"#).is_empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn dashes() {
|
fn dashes() {
|
||||||
assert_eq!(count_em_dashes("a — b -- c ---d"), 2);
|
assert_eq!(count_em_dashes("a — b -- c ---d"), 2);
|
||||||
|
|||||||
@@ -57,6 +57,28 @@ fn cmd_launcher_asset_naming_matches_engine() {
|
|||||||
assert!(!cmd.contains("npm i -g"));
|
assert!(!cmd.contains("npm i -g"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cmd_launcher_forwards_engine_exit_code() {
|
||||||
|
// Bare `exit /b` drops the process exit code when this file is cmd.exe's
|
||||||
|
// entry point (cmd /c, PowerShell, Node spawn). Forward %errorlevel%
|
||||||
|
// after each engine invocation instead.
|
||||||
|
let cmd = launcher_file("impeccable.cmd");
|
||||||
|
for (i, line) in cmd.lines().enumerate() {
|
||||||
|
assert_ne!(
|
||||||
|
line.trim(),
|
||||||
|
"exit /b",
|
||||||
|
"impeccable.cmd line {}: bare exit /b drops the process code: {line}",
|
||||||
|
i + 1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let forward = "exit /b %errorlevel%";
|
||||||
|
assert_eq!(
|
||||||
|
cmd.matches(forward).count(),
|
||||||
|
2,
|
||||||
|
"PATH candidate and :run must both forward the engine exit code"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn cmd_launcher_has_no_multiline_parenthesized_blocks() {
|
fn cmd_launcher_has_no_multiline_parenthesized_blocks() {
|
||||||
// cmd.exe expands %var% inside a parenthesized block at parse time, so a
|
// cmd.exe expands %var% inside a parenthesized block at parse time, so a
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ if errorlevel 1 goto download
|
|||||||
call :probe impeccable
|
call :probe impeccable
|
||||||
if not "%probe_ok%"=="1" goto download
|
if not "%probe_ok%"=="1" goto download
|
||||||
impeccable %*
|
impeccable %*
|
||||||
exit /b
|
exit /b %errorlevel%
|
||||||
|
|
||||||
:download
|
:download
|
||||||
rem Last resort: fetch this version's binary from the release channel into
|
rem Last resort: fetch this version's binary from the release channel into
|
||||||
@@ -166,7 +166,7 @@ exit /b 127
|
|||||||
|
|
||||||
:run
|
:run
|
||||||
"%run%" %*
|
"%run%" %*
|
||||||
exit /b
|
exit /b %errorlevel%
|
||||||
|
|
||||||
:probe
|
:probe
|
||||||
rem Sets probe_ok=1 when %1 answers the engine handshake: prints
|
rem Sets probe_ok=1 when %1 answers the engine handshake: prints
|
||||||
|
|||||||
@@ -174,6 +174,34 @@ test('launcher downloads and runs a verified executable', async t => {
|
|||||||
assert.equal(result.requests.length, 2);
|
assert.equal(result.requests.length, 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('cmd launcher forwards engine exit code through cmd /c', { skip: WINDOWS ? false : 'Windows-only cmd /c exit-code forwarding' }, async t => {
|
||||||
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'impeccable-launcher-exit-'));
|
||||||
|
t.after(() => fs.rmSync(root, { recursive: true, force: true }));
|
||||||
|
const home = path.join(root, 'home');
|
||||||
|
fs.mkdirSync(home);
|
||||||
|
const launcher = path.join(root, 'impeccable.cmd');
|
||||||
|
fs.copyFileSync(path.join(ROOT, 'skill/scripts/impeccable.cmd'), launcher);
|
||||||
|
const env = {
|
||||||
|
PATH: `${process.env.SystemRoot}\\System32;${process.env.SystemRoot}`,
|
||||||
|
HOME: home, USERPROFILE: home, TEMP: root, TMP: root,
|
||||||
|
IMPECCABLE_HOME: path.join(root, 'cache'),
|
||||||
|
IMPECCABLE_BIN: COMSPEC,
|
||||||
|
SystemRoot: process.env.SystemRoot,
|
||||||
|
ComSpec: COMSPEC,
|
||||||
|
PROCESSOR_ARCHITECTURE: 'AMD64',
|
||||||
|
};
|
||||||
|
const run = (args) => new Promise((resolve, reject) => {
|
||||||
|
const child = spawn(COMSPEC, ['/d', '/s', '/c', `""${launcher}" ${args}"`], { env, cwd: root, windowsVerbatimArguments: true, timeout: 20000 });
|
||||||
|
child.on('error', reject);
|
||||||
|
child.on('close', (status, signal) => resolve({ status, signal }));
|
||||||
|
});
|
||||||
|
for (const [args, expected] of [['/c exit 2', 2], ['/c exit 1', 1], ['/c exit 0', 0]]) {
|
||||||
|
const result = await run(args);
|
||||||
|
assert.equal(result.signal, null, JSON.stringify(result));
|
||||||
|
assert.equal(result.status, expected, args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
for (const scenario of ['removed', 'emptied', 'empty-download', 'no-sidecar', 'empty-sidecar', 'mismatch', 'hash-failure', 'removed-during-hash', 'removed-before-move', 'removed-after-move', 'emptied-after-move', 'move-failure']) {
|
for (const scenario of ['removed', 'emptied', 'empty-download', 'no-sidecar', 'empty-sidecar', 'mismatch', 'hash-failure', 'removed-during-hash', 'removed-before-move', 'removed-after-move', 'emptied-after-move', 'move-failure']) {
|
||||||
test(`launcher refuses ${scenario} with an accurate diagnostic`, async t => {
|
test(`launcher refuses ${scenario} with an accurate diagnostic`, async t => {
|
||||||
const result = await exercise(t, scenario);
|
const result = await exercise(t, scenario);
|
||||||
|
|||||||
Reference in New Issue
Block a user